[ Upstream commit 5e844cc37a5cbaa460e68f9a989d321d63088a89 ]
SPI driver probing currently comprises two steps, whereas removal comprises only one step:
spi_alloc_master() spi_register_controller()
spi_unregister_controller()
That's because spi_unregister_controller() calls device_unregister() instead of device_del(), thereby releasing the reference on the spi_controller which was obtained by spi_alloc_master().
An SPI driver's private data is contained in the same memory allocation as the spi_controller struct. Thus, once spi_unregister_controller() has been called, the private data is inaccessible. But some drivers need to access it after spi_unregister_controller() to perform further teardown steps.
Introduce devm_spi_alloc_master() and devm_spi_alloc_slave(), which release a reference on the spi_controller struct only after the driver has unbound, thereby keeping the memory allocation accessible. Change spi_unregister_controller() to not release a reference if the spi_controller was allocated by one of these new devm functions.
The present commit is small enough to be backportable to stable. It allows fixing drivers which use the private data in their ->remove() hook after it's been freed. It also allows fixing drivers which neglect to release a reference on the spi_controller in the probe error path.
Long-term, most SPI drivers shall be moved over to the devm functions introduced herein. The few that can't shall be changed in a treewide commit to explicitly release the last reference on the controller. That commit shall amend spi_unregister_controller() to no longer release a reference, thereby completing the migration.
As a result, the behaviour will be less surprising and more consistent with subsystems such as IIO, which also includes the private data in the allocation of the generic iio_dev struct, but calls device_del() in iio_device_unregister().
Signed-off-by: Lukas Wunner lukas@wunner.de Link: https://lore.kernel.org/r/272bae2ef08abd21388c98e23729886663d19192.160512103... Signed-off-by: Mark Brown broonie@kernel.org --- drivers/spi/spi.c | 58 ++++++++++++++++++++++++++++++++++++++++- include/linux/spi/spi.h | 19 ++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 1fd529a2d2f6..fbc5444bd9cb 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -2050,6 +2050,49 @@ struct spi_controller *__spi_alloc_controller(struct device *dev, } EXPORT_SYMBOL_GPL(__spi_alloc_controller);
+static void devm_spi_release_controller(struct device *dev, void *ctlr) +{ + spi_controller_put(*(struct spi_controller **)ctlr); +} + +/** + * __devm_spi_alloc_controller - resource-managed __spi_alloc_controller() + * @dev: physical device of SPI controller + * @size: how much zeroed driver-private data to allocate + * @slave: whether to allocate an SPI master (false) or SPI slave (true) + * Context: can sleep + * + * Allocate an SPI controller and automatically release a reference on it + * when @dev is unbound from its driver. Drivers are thus relieved from + * having to call spi_controller_put(). + * + * The arguments to this function are identical to __spi_alloc_controller(). + * + * Return: the SPI controller structure on success, else NULL. + */ +struct spi_controller *__devm_spi_alloc_controller(struct device *dev, + unsigned int size, + bool slave) +{ + struct spi_controller **ptr, *ctlr; + + ptr = devres_alloc(devm_spi_release_controller, sizeof(*ptr), + GFP_KERNEL); + if (!ptr) + return NULL; + + ctlr = __spi_alloc_controller(dev, size, slave); + if (ctlr) { + *ptr = ctlr; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return ctlr; +} +EXPORT_SYMBOL_GPL(__devm_spi_alloc_controller); + #ifdef CONFIG_OF static int of_spi_register_master(struct spi_controller *ctlr) { @@ -2300,6 +2343,11 @@ int devm_spi_register_controller(struct device *dev, } EXPORT_SYMBOL_GPL(devm_spi_register_controller);
+static int devm_spi_match_controller(struct device *dev, void *res, void *ctlr) +{ + return *(struct spi_controller **)res == ctlr; +} + static int __unregister(struct device *dev, void *null) { spi_unregister_device(to_spi_device(dev)); @@ -2341,7 +2389,15 @@ void spi_unregister_controller(struct spi_controller *ctlr) list_del(&ctlr->list); mutex_unlock(&board_lock);
- device_unregister(&ctlr->dev); + device_del(&ctlr->dev); + + /* Release the last reference on the controller if its driver + * has not yet been converted to devm_spi_alloc_master/slave(). + */ + if (!devres_find(ctlr->dev.parent, devm_spi_release_controller, + devm_spi_match_controller, ctlr)) + put_device(&ctlr->dev); + /* free bus id */ mutex_lock(&board_lock); if (found == ctlr) diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index a64235e05321..8ceba9b8e51e 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -634,6 +634,25 @@ static inline struct spi_controller *spi_alloc_slave(struct device *host, return __spi_alloc_controller(host, size, true); }
+struct spi_controller *__devm_spi_alloc_controller(struct device *dev, + unsigned int size, + bool slave); + +static inline struct spi_controller *devm_spi_alloc_master(struct device *dev, + unsigned int size) +{ + return __devm_spi_alloc_controller(dev, size, false); +} + +static inline struct spi_controller *devm_spi_alloc_slave(struct device *dev, + unsigned int size) +{ + if (!IS_ENABLED(CONFIG_SPI_SLAVE)) + return NULL; + + return __devm_spi_alloc_controller(dev, size, true); +} + extern int spi_register_controller(struct spi_controller *ctlr); extern int devm_spi_register_controller(struct device *dev, struct spi_controller *ctlr);
commit 63c5395bb7a9777a33f0e7b5906f2c0170a23692 upstream
bcm_qspi_remove() calls spi_unregister_master() even though bcm_qspi_probe() calls devm_spi_register_master(). The spi_master is therefore unregistered and freed twice on unbind.
Moreover, since commit 0392727c261b ("spi: bcm-qspi: Handle clock probe deferral"), bcm_qspi_probe() leaks the spi_master allocation if the call to devm_clk_get_optional() fails.
Fix by switching over to the new devm_spi_alloc_master() helper which keeps the private data accessible until the driver has unbound and also avoids the spi_master leak on probe.
While at it, fix an ordering issue in bcm_qspi_remove() wherein spi_unregister_master() is called after uninitializing the hardware, disabling the clock and freeing an IRQ data structure. The correct order is to call spi_unregister_master() *before* those teardown steps because bus accesses may still be ongoing until that function returns.
Fixes: fa236a7ef240 ("spi: bcm-qspi: Add Broadcom MSPI driver") Signed-off-by: Lukas Wunner lukas@wunner.de Cc: stable@vger.kernel.org # v4.9+: 123456789abc: spi: Introduce device-managed SPI controller allocation Cc: stable@vger.kernel.org # v4.9+ Cc: Kamal Dasu kdasu.kdev@gmail.com Acked-by: Florian Fainelli f.fainelli@gmail.com Tested-by: Florian Fainelli f.fainelli@gmail.com Link: https://lore.kernel.org/r/5e31a9a59fd1c0d0b795b2fe219f25e5ee855f9d.160512103... Signed-off-by: Mark Brown broonie@kernel.org [sudip: adjust context] Signed-off-by: Sudip Mukherjee sudipm.mukherjee@gmail.com --- drivers/spi/spi-bcm-qspi.c | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-)
diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c index 2145a70dac69..4ee92f7ca20b 100644 --- a/drivers/spi/spi-bcm-qspi.c +++ b/drivers/spi/spi-bcm-qspi.c @@ -1223,7 +1223,7 @@ int bcm_qspi_probe(struct platform_device *pdev, if (!of_match_node(bcm_qspi_of_match, dev->of_node)) return -ENODEV;
- master = spi_alloc_master(dev, sizeof(struct bcm_qspi)); + master = devm_spi_alloc_master(dev, sizeof(struct bcm_qspi)); if (!master) { dev_err(dev, "error allocating spi_master\n"); return -ENOMEM; @@ -1257,21 +1257,17 @@ int bcm_qspi_probe(struct platform_device *pdev,
if (res) { qspi->base[MSPI] = devm_ioremap_resource(dev, res); - if (IS_ERR(qspi->base[MSPI])) { - ret = PTR_ERR(qspi->base[MSPI]); - goto qspi_resource_err; - } + if (IS_ERR(qspi->base[MSPI])) + return PTR_ERR(qspi->base[MSPI]); } else { - goto qspi_resource_err; + return 0; }
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bspi"); if (res) { qspi->base[BSPI] = devm_ioremap_resource(dev, res); - if (IS_ERR(qspi->base[BSPI])) { - ret = PTR_ERR(qspi->base[BSPI]); - goto qspi_resource_err; - } + if (IS_ERR(qspi->base[BSPI])) + return PTR_ERR(qspi->base[BSPI]); qspi->bspi_mode = true; } else { qspi->bspi_mode = false; @@ -1282,18 +1278,14 @@ int bcm_qspi_probe(struct platform_device *pdev, res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cs_reg"); if (res) { qspi->base[CHIP_SELECT] = devm_ioremap_resource(dev, res); - if (IS_ERR(qspi->base[CHIP_SELECT])) { - ret = PTR_ERR(qspi->base[CHIP_SELECT]); - goto qspi_resource_err; - } + if (IS_ERR(qspi->base[CHIP_SELECT])) + return PTR_ERR(qspi->base[CHIP_SELECT]); }
qspi->dev_ids = kcalloc(num_irqs, sizeof(struct bcm_qspi_dev_id), GFP_KERNEL); - if (!qspi->dev_ids) { - ret = -ENOMEM; - goto qspi_resource_err; - } + if (!qspi->dev_ids) + return -ENOMEM;
for (val = 0; val < num_irqs; val++) { irq = -1; @@ -1369,7 +1361,7 @@ int bcm_qspi_probe(struct platform_device *pdev, qspi->xfer_mode.addrlen = -1; qspi->xfer_mode.hp = -1;
- ret = devm_spi_register_master(&pdev->dev, master); + ret = spi_register_master(master); if (ret < 0) { dev_err(dev, "can't register master\n"); goto qspi_reg_err; @@ -1382,8 +1374,6 @@ int bcm_qspi_probe(struct platform_device *pdev, clk_disable_unprepare(qspi->clk); qspi_probe_err: kfree(qspi->dev_ids); -qspi_resource_err: - spi_master_put(master); return ret; } /* probe function to be called by SoC specific platform driver probe */ @@ -1393,10 +1383,10 @@ int bcm_qspi_remove(struct platform_device *pdev) { struct bcm_qspi *qspi = platform_get_drvdata(pdev);
+ spi_unregister_master(qspi->master); bcm_qspi_hw_uninit(qspi); clk_disable_unprepare(qspi->clk); kfree(qspi->dev_ids); - spi_unregister_master(qspi->master);
return 0; }
[ Upstream commit e1483ac030fb4c57734289742f1c1d38dca61e22 ]
bcm2835_spi_remove() accesses the driver's private data after calling spi_unregister_controller() even though that function releases the last reference on the spi_controller and thereby frees the private data.
Fix by switching over to the new devm_spi_alloc_master() helper which keeps the private data accessible until the driver has unbound.
Fixes: f8043872e796 ("spi: add driver for BCM2835") Reported-by: Sascha Hauer s.hauer@pengutronix.de Reported-by: Florian Fainelli f.fainelli@gmail.com Signed-off-by: Lukas Wunner lukas@wunner.de Cc: stable@vger.kernel.org # v3.10+: 5e844cc37a5c: spi: Introduce device-managed SPI controller allocation Cc: stable@vger.kernel.org # v3.10+ Cc: Vladimir Oltean olteanv@gmail.com Tested-by: Florian Fainelli f.fainelli@gmail.com Acked-by: Florian Fainelli f.fainelli@gmail.com Link: https://lore.kernel.org/r/ad66e0a0ad96feb848814842ecf5b6a4539ef35c.160512103... Signed-off-by: Mark Brown broonie@kernel.org --- drivers/spi/spi-bcm2835.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-)
diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index df6abc75bc16..2908df35466f 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -737,7 +737,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev) struct resource *res; int err;
- master = spi_alloc_master(&pdev->dev, sizeof(*bs)); + master = devm_spi_alloc_master(&pdev->dev, sizeof(*bs)); if (!master) { dev_err(&pdev->dev, "spi_alloc_master() failed\n"); return -ENOMEM; @@ -759,23 +759,20 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); bs->regs = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(bs->regs)) { - err = PTR_ERR(bs->regs); - goto out_master_put; - } + if (IS_ERR(bs->regs)) + return PTR_ERR(bs->regs);
bs->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(bs->clk)) { err = PTR_ERR(bs->clk); dev_err(&pdev->dev, "could not get clk: %d\n", err); - goto out_master_put; + return err; }
bs->irq = platform_get_irq(pdev, 0); if (bs->irq <= 0) { dev_err(&pdev->dev, "could not get IRQ: %d\n", bs->irq); - err = bs->irq ? bs->irq : -ENODEV; - goto out_master_put; + return bs->irq ? bs->irq : -ENODEV; }
clk_prepare_enable(bs->clk); @@ -803,8 +800,6 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
out_clk_disable: clk_disable_unprepare(bs->clk); -out_master_put: - spi_master_put(master); return err; }
[ Upstream commit e13ee6cc4781edaf8c7321bee19217e3702ed481 ]
bcm2835aux_spi_remove() accesses the driver's private data after calling spi_unregister_master() even though that function releases the last reference on the spi_master and thereby frees the private data.
Fix by switching over to the new devm_spi_alloc_master() helper which keeps the private data accessible until the driver has unbound.
Fixes: b9dd3f6d4172 ("spi: bcm2835aux: Fix controller unregister order") Signed-off-by: Lukas Wunner lukas@wunner.de Cc: stable@vger.kernel.org # v4.4+: 5e844cc37a5c: spi: Introduce device-managed SPI controller allocation Cc: stable@vger.kernel.org # v4.4+: b9dd3f6d4172: spi: bcm2835aux: Fix controller unregister order Cc: stable@vger.kernel.org # v4.4+ Link: https://lore.kernel.org/r/b290b06357d0c0bdee9cecc539b840a90630f101.160512103... Signed-off-by: Mark Brown broonie@kernel.org --- drivers/spi/spi-bcm2835aux.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/drivers/spi/spi-bcm2835aux.c b/drivers/spi/spi-bcm2835aux.c index 11895c98aae3..8ea7e31b8c2f 100644 --- a/drivers/spi/spi-bcm2835aux.c +++ b/drivers/spi/spi-bcm2835aux.c @@ -407,7 +407,7 @@ static int bcm2835aux_spi_probe(struct platform_device *pdev) unsigned long clk_hz; int err;
- master = spi_alloc_master(&pdev->dev, sizeof(*bs)); + master = devm_spi_alloc_master(&pdev->dev, sizeof(*bs)); if (!master) { dev_err(&pdev->dev, "spi_alloc_master() failed\n"); return -ENOMEM; @@ -439,30 +439,27 @@ static int bcm2835aux_spi_probe(struct platform_device *pdev) /* the main area */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); bs->regs = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(bs->regs)) { - err = PTR_ERR(bs->regs); - goto out_master_put; - } + if (IS_ERR(bs->regs)) + return PTR_ERR(bs->regs);
bs->clk = devm_clk_get(&pdev->dev, NULL); if ((!bs->clk) || (IS_ERR(bs->clk))) { err = PTR_ERR(bs->clk); dev_err(&pdev->dev, "could not get clk: %d\n", err); - goto out_master_put; + return err; }
bs->irq = platform_get_irq(pdev, 0); if (bs->irq <= 0) { dev_err(&pdev->dev, "could not get IRQ: %d\n", bs->irq); - err = bs->irq ? bs->irq : -ENODEV; - goto out_master_put; + return bs->irq ? bs->irq : -ENODEV; }
/* this also enables the HW block */ err = clk_prepare_enable(bs->clk); if (err) { dev_err(&pdev->dev, "could not prepare clock: %d\n", err); - goto out_master_put; + return err; }
/* just checking if the clock returns a sane value */ @@ -495,8 +492,6 @@ static int bcm2835aux_spi_probe(struct platform_device *pdev)
out_clk_disable: clk_disable_unprepare(bs->clk); -out_master_put: - spi_master_put(master); return err; }
On Sun, Dec 06, 2020 at 01:31:03PM +0100, Lukas Wunner wrote:
[ Upstream commit e13ee6cc4781edaf8c7321bee19217e3702ed481 ]
bcm2835aux_spi_remove() accesses the driver's private data after calling spi_unregister_master() even though that function releases the last reference on the spi_master and thereby frees the private data.
Fix by switching over to the new devm_spi_alloc_master() helper which keeps the private data accessible until the driver has unbound.
Fixes: b9dd3f6d4172 ("spi: bcm2835aux: Fix controller unregister order") Signed-off-by: Lukas Wunner lukas@wunner.de Cc: stable@vger.kernel.org # v4.4+: 5e844cc37a5c: spi: Introduce device-managed SPI controller allocation Cc: stable@vger.kernel.org # v4.4+: b9dd3f6d4172: spi: bcm2835aux: Fix controller unregister order Cc: stable@vger.kernel.org # v4.4+ Link: https://lore.kernel.org/r/b290b06357d0c0bdee9cecc539b840a90630f101.160512103... Signed-off-by: Mark Brown broonie@kernel.org
Please ensure that commit d853b3406903 ("spi: bcm2835aux: Restore err assignment in bcm2835aux_spi_probe") is picked up with this patch in all of the stable trees that it is applied to.
Cheers, Nathan
On Mon, Dec 07, 2020 at 05:49:01PM -0700, Nathan Chancellor wrote:
On Sun, Dec 06, 2020 at 01:31:03PM +0100, Lukas Wunner wrote:
[ Upstream commit e13ee6cc4781edaf8c7321bee19217e3702ed481 ]
bcm2835aux_spi_remove() accesses the driver's private data after calling spi_unregister_master() even though that function releases the last reference on the spi_master and thereby frees the private data.
Fix by switching over to the new devm_spi_alloc_master() helper which keeps the private data accessible until the driver has unbound.
Fixes: b9dd3f6d4172 ("spi: bcm2835aux: Fix controller unregister order") Signed-off-by: Lukas Wunner lukas@wunner.de Cc: stable@vger.kernel.org # v4.4+: 5e844cc37a5c: spi: Introduce device-managed SPI controller allocation Cc: stable@vger.kernel.org # v4.4+: b9dd3f6d4172: spi: bcm2835aux: Fix controller unregister order Cc: stable@vger.kernel.org # v4.4+ Link: https://lore.kernel.org/r/b290b06357d0c0bdee9cecc539b840a90630f101.160512103... Signed-off-by: Mark Brown broonie@kernel.org
Please ensure that commit d853b3406903 ("spi: bcm2835aux: Restore err assignment in bcm2835aux_spi_probe") is picked up with this patch in all of the stable trees that it is applied to.
That shouldn't be necessary as I've made sure that the backports to 4.19 and earlier do not exhibit the issue fixed by d853b3406903.
However, nobody is perfect, so if I've missed anything, please let me know.
Thanks!
Lukas
On Tue, Dec 08, 2020 at 08:32:41AM +0100, Lukas Wunner wrote:
On Mon, Dec 07, 2020 at 05:49:01PM -0700, Nathan Chancellor wrote:
On Sun, Dec 06, 2020 at 01:31:03PM +0100, Lukas Wunner wrote:
[ Upstream commit e13ee6cc4781edaf8c7321bee19217e3702ed481 ]
bcm2835aux_spi_remove() accesses the driver's private data after calling spi_unregister_master() even though that function releases the last reference on the spi_master and thereby frees the private data.
Fix by switching over to the new devm_spi_alloc_master() helper which keeps the private data accessible until the driver has unbound.
Fixes: b9dd3f6d4172 ("spi: bcm2835aux: Fix controller unregister order") Signed-off-by: Lukas Wunner lukas@wunner.de Cc: stable@vger.kernel.org # v4.4+: 5e844cc37a5c: spi: Introduce device-managed SPI controller allocation Cc: stable@vger.kernel.org # v4.4+: b9dd3f6d4172: spi: bcm2835aux: Fix controller unregister order Cc: stable@vger.kernel.org # v4.4+ Link: https://lore.kernel.org/r/b290b06357d0c0bdee9cecc539b840a90630f101.160512103... Signed-off-by: Mark Brown broonie@kernel.org
Please ensure that commit d853b3406903 ("spi: bcm2835aux: Restore err assignment in bcm2835aux_spi_probe") is picked up with this patch in all of the stable trees that it is applied to.
That shouldn't be necessary as I've made sure that the backports to 4.19 and earlier do not exhibit the issue fixed by d853b3406903.
However, nobody is perfect, so if I've missed anything, please let me know.
Could we instead have the backports exhibit the issue (like they did upstream) and then take d853b3406903 on top?
On Tue, Dec 08, 2020 at 08:47:39AM -0500, Sasha Levin wrote:
On Tue, Dec 08, 2020 at 08:32:41AM +0100, Lukas Wunner wrote:
On Mon, Dec 07, 2020 at 05:49:01PM -0700, Nathan Chancellor wrote:
On Sun, Dec 06, 2020 at 01:31:03PM +0100, Lukas Wunner wrote:
[ Upstream commit e13ee6cc4781edaf8c7321bee19217e3702ed481 ]
bcm2835aux_spi_remove() accesses the driver's private data after calling spi_unregister_master() even though that function releases the last reference on the spi_master and thereby frees the private data.
Fix by switching over to the new devm_spi_alloc_master() helper which keeps the private data accessible until the driver has unbound.
Fixes: b9dd3f6d4172 ("spi: bcm2835aux: Fix controller unregister order") Signed-off-by: Lukas Wunner lukas@wunner.de Cc: stable@vger.kernel.org # v4.4+: 5e844cc37a5c: spi: Introduce device-managed SPI controller allocation Cc: stable@vger.kernel.org # v4.4+: b9dd3f6d4172: spi: bcm2835aux: Fix controller unregister order Cc: stable@vger.kernel.org # v4.4+ Link: https://lore.kernel.org/r/b290b06357d0c0bdee9cecc539b840a90630f101.160512103... Signed-off-by: Mark Brown broonie@kernel.org
Please ensure that commit d853b3406903 ("spi: bcm2835aux: Restore err assignment in bcm2835aux_spi_probe") is picked up with this patch in all of the stable trees that it is applied to.
That shouldn't be necessary as I've made sure that the backports to 4.19 and earlier do not exhibit the issue fixed by d853b3406903.
However, nobody is perfect, so if I've missed anything, please let me know.
Could we instead have the backports exhibit the issue (like they did upstream) and then take d853b3406903 on top?
The upstream commit e13ee6cc4781 did not apply cleanly to 4.19 and earlier, several adjustments were required. Could I have made it so that the fixup d853b3406903 would have still been required? Probably, but it seems a little silly to submit a known-bad patch.
Thanks,
Lukas
On Tue, Dec 08, 2020 at 06:11:45PM +0100, Lukas Wunner wrote:
On Tue, Dec 08, 2020 at 08:47:39AM -0500, Sasha Levin wrote:
On Tue, Dec 08, 2020 at 08:32:41AM +0100, Lukas Wunner wrote:
On Mon, Dec 07, 2020 at 05:49:01PM -0700, Nathan Chancellor wrote:
On Sun, Dec 06, 2020 at 01:31:03PM +0100, Lukas Wunner wrote:
[ Upstream commit e13ee6cc4781edaf8c7321bee19217e3702ed481 ]
bcm2835aux_spi_remove() accesses the driver's private data after calling spi_unregister_master() even though that function releases the last reference on the spi_master and thereby frees the private data.
Fix by switching over to the new devm_spi_alloc_master() helper which keeps the private data accessible until the driver has unbound.
Fixes: b9dd3f6d4172 ("spi: bcm2835aux: Fix controller unregister order") Signed-off-by: Lukas Wunner lukas@wunner.de Cc: stable@vger.kernel.org # v4.4+: 5e844cc37a5c: spi: Introduce device-managed SPI controller allocation Cc: stable@vger.kernel.org # v4.4+: b9dd3f6d4172: spi: bcm2835aux: Fix controller unregister order Cc: stable@vger.kernel.org # v4.4+ Link: https://lore.kernel.org/r/b290b06357d0c0bdee9cecc539b840a90630f101.160512103... Signed-off-by: Mark Brown broonie@kernel.org
Please ensure that commit d853b3406903 ("spi: bcm2835aux: Restore err assignment in bcm2835aux_spi_probe") is picked up with this patch in all of the stable trees that it is applied to.
That shouldn't be necessary as I've made sure that the backports to 4.19 and earlier do not exhibit the issue fixed by d853b3406903.
However, nobody is perfect, so if I've missed anything, please let me know.
Could we instead have the backports exhibit the issue (like they did upstream) and then take d853b3406903 on top?
The upstream commit e13ee6cc4781 did not apply cleanly to 4.19 and earlier, several adjustments were required. Could I have made it so that the fixup d853b3406903 would have still been required? Probably, but it seems a little silly to submit a known-bad patch.
Thanks,
Lukas
I did not really look at the actual patches themselves, just the fact that I saw the commit title without my patch as a follow up in the series. If your backport avoids the issue entirely, that is fine by me.
Cheers, Nathan
On Tue, Dec 08, 2020 at 06:11:45PM +0100, Lukas Wunner wrote:
On Tue, Dec 08, 2020 at 08:47:39AM -0500, Sasha Levin wrote:
On Tue, Dec 08, 2020 at 08:32:41AM +0100, Lukas Wunner wrote:
On Mon, Dec 07, 2020 at 05:49:01PM -0700, Nathan Chancellor wrote:
On Sun, Dec 06, 2020 at 01:31:03PM +0100, Lukas Wunner wrote:
[ Upstream commit e13ee6cc4781edaf8c7321bee19217e3702ed481 ]
bcm2835aux_spi_remove() accesses the driver's private data after calling spi_unregister_master() even though that function releases the last reference on the spi_master and thereby frees the private data.
Fix by switching over to the new devm_spi_alloc_master() helper which keeps the private data accessible until the driver has unbound.
Fixes: b9dd3f6d4172 ("spi: bcm2835aux: Fix controller unregister order") Signed-off-by: Lukas Wunner lukas@wunner.de Cc: stable@vger.kernel.org # v4.4+: 5e844cc37a5c: spi: Introduce device-managed SPI controller allocation Cc: stable@vger.kernel.org # v4.4+: b9dd3f6d4172: spi: bcm2835aux: Fix controller unregister order Cc: stable@vger.kernel.org # v4.4+ Link: https://lore.kernel.org/r/b290b06357d0c0bdee9cecc539b840a90630f101.160512103... Signed-off-by: Mark Brown broonie@kernel.org
Please ensure that commit d853b3406903 ("spi: bcm2835aux: Restore err assignment in bcm2835aux_spi_probe") is picked up with this patch in all of the stable trees that it is applied to.
That shouldn't be necessary as I've made sure that the backports to 4.19 and earlier do not exhibit the issue fixed by d853b3406903.
However, nobody is perfect, so if I've missed anything, please let me know.
Could we instead have the backports exhibit the issue (like they did upstream) and then take d853b3406903 on top?
The upstream commit e13ee6cc4781 did not apply cleanly to 4.19 and earlier, several adjustments were required. Could I have made it so that the fixup d853b3406903 would have still been required? Probably, but it seems a little silly to submit a known-bad patch.
Not silly, there are two motives here:
1. We don't want to diverge too much with backports, which means that they need to be minimal. 2. It'll make auditing later easier. What will happen now is that after this patch is merges, we'll trigger a warning saying that there's a fix upstream for one of these patches, and we'll end up wasting the time (of probably a few folks) figuring this out.
Note I'm not asking to submit a broken patch, but I'm asking to submit a minimal backport followed by the upstream fix to that upstream bug :)
On Tue, Dec 08, 2020 at 04:17:45PM -0500, Sasha Levin wrote:
On Tue, Dec 08, 2020 at 06:11:45PM +0100, Lukas Wunner wrote:
On Tue, Dec 08, 2020 at 08:47:39AM -0500, Sasha Levin wrote:
Could we instead have the backports exhibit the issue (like they did upstream) and then take d853b3406903 on top?
The upstream commit e13ee6cc4781 did not apply cleanly to 4.19 and earlier, several adjustments were required. Could I have made it so that the fixup d853b3406903 would have still been required? Probably, but it seems a little silly to submit a known-bad patch.
[...]
- It'll make auditing later easier. What will happen now is that after
this patch is merges, we'll trigger a warning saying that there's a fix upstream for one of these patches, and we'll end up wasting the time (of probably a few folks) figuring this out.
Would it be possible to amend the tooling such that multiple "[ Upstream commit ... ]" lines are supported at the top of the commit message, signifying that the backport patch subsumes all cited upstream commits?
Could the extra work for stable maintainers be avoided that way?
I imagine there might be more cases where a "clean" backport is not possible, requiring multiple upstream patches to be combined.
Note I'm not asking to submit a broken patch, but I'm asking to submit a minimal backport followed by the upstream fix to that upstream bug :)
Then please apply the series sans bcm2835aux patch and I'll follow up with a two-patch series specifically for that driver.
Alternatively, please consider whether multiple "[ Upstream commit ... ]" lines would be a viable solution and if it is, add a line as follows when applying the bcm2835aux patch:
[ Upstream commit d853b3406903a7dc5b14eb5bada3e8cd677f66a2 ]
Thanks,
Lukas
On Wed, Dec 09, 2020 at 09:37:47AM +0100, Lukas Wunner wrote:
On Tue, Dec 08, 2020 at 04:17:45PM -0500, Sasha Levin wrote:
On Tue, Dec 08, 2020 at 06:11:45PM +0100, Lukas Wunner wrote:
On Tue, Dec 08, 2020 at 08:47:39AM -0500, Sasha Levin wrote:
Could we instead have the backports exhibit the issue (like they did upstream) and then take d853b3406903 on top?
The upstream commit e13ee6cc4781 did not apply cleanly to 4.19 and earlier, several adjustments were required. Could I have made it so that the fixup d853b3406903 would have still been required? Probably, but it seems a little silly to submit a known-bad patch.
[...]
- It'll make auditing later easier. What will happen now is that after
this patch is merges, we'll trigger a warning saying that there's a fix upstream for one of these patches, and we'll end up wasting the time (of probably a few folks) figuring this out.
Would it be possible to amend the tooling such that multiple "[ Upstream commit ... ]" lines are supported at the top of the commit message, signifying that the backport patch subsumes all cited upstream commits?
You could, but that's extra work, which I think you are trying to avoid when you say:
Could the extra work for stable maintainers be avoided that way?
this :)
I imagine there might be more cases where a "clean" backport is not possible, requiring multiple upstream patches to be combined.
It is quite rare. And again, it's almost always better to just take all of the patches involved, as individual patches, that way we "know" we did it right, and it's easier to track and audit and review that way.
Note I'm not asking to submit a broken patch, but I'm asking to submit a minimal backport followed by the upstream fix to that upstream bug :)
Then please apply the series sans bcm2835aux patch and I'll follow up with a two-patch series specifically for that driver.
Can you just resend the whole series so we know we got it correct?
thanks,
greg k-h
On Wed, Dec 09, 2020 at 10:36:55AM +0100, Greg KH wrote:
On Wed, Dec 09, 2020 at 09:37:47AM +0100, Lukas Wunner wrote:
Then please apply the series sans bcm2835aux patch and I'll follow up with a two-patch series specifically for that driver.
Can you just resend the whole series so we know we got it correct?
The other patches in the series do not depend on the bcm2835aux patch, so you can apply them independently.
Thanks,
Lukas
On Wed, Dec 09, 2020 at 10:38:18AM +0100, Lukas Wunner wrote:
On Wed, Dec 09, 2020 at 10:36:55AM +0100, Greg KH wrote:
On Wed, Dec 09, 2020 at 09:37:47AM +0100, Lukas Wunner wrote:
Then please apply the series sans bcm2835aux patch and I'll follow up with a two-patch series specifically for that driver.
Can you just resend the whole series so we know we got it correct?
The other patches in the series do not depend on the bcm2835aux patch, so you can apply them independently.
Ok, so I need to drop this patch from all of the other series you sent out? You can see how this is getting messy from my side :)
thanks,
greg k-h
On Wed, Dec 09, 2020 at 10:44:59AM +0100, Greg KH wrote:
On Wed, Dec 09, 2020 at 10:38:18AM +0100, Lukas Wunner wrote:
On Wed, Dec 09, 2020 at 10:36:55AM +0100, Greg KH wrote:
On Wed, Dec 09, 2020 at 09:37:47AM +0100, Lukas Wunner wrote:
Then please apply the series sans bcm2835aux patch and I'll follow up with a two-patch series specifically for that driver.
Can you just resend the whole series so we know we got it correct?
The other patches in the series do not depend on the bcm2835aux patch, so you can apply them independently.
Ok, so I need to drop this patch from all of the other series you sent out? You can see how this is getting messy from my side :)
Is this workflow description still up-to-date?
http://kroah.com/log/blog/2019/08/14/patch-workflow-with-mutt-2019/
So you just select all patches in Mutt sans the bcm2835aux one and apply them?
No I don't see how this is getting messy.
Thanks,
Lukas
On Thu, Dec 10, 2020 at 08:01:42AM +0100, Lukas Wunner wrote:
On Wed, Dec 09, 2020 at 10:44:59AM +0100, Greg KH wrote:
On Wed, Dec 09, 2020 at 10:38:18AM +0100, Lukas Wunner wrote:
On Wed, Dec 09, 2020 at 10:36:55AM +0100, Greg KH wrote:
On Wed, Dec 09, 2020 at 09:37:47AM +0100, Lukas Wunner wrote:
Then please apply the series sans bcm2835aux patch and I'll follow up with a two-patch series specifically for that driver.
Can you just resend the whole series so we know we got it correct?
The other patches in the series do not depend on the bcm2835aux patch, so you can apply them independently.
Ok, so I need to drop this patch from all of the other series you sent out? You can see how this is getting messy from my side :)
Is this workflow description still up-to-date?
http://kroah.com/log/blog/2019/08/14/patch-workflow-with-mutt-2019/
So you just select all patches in Mutt sans the bcm2835aux one and apply them?
No I don't see how this is getting messy.
The less "special" steps I have to make, the less chance I mess something up :)
I've queued these up now, please check that I got it right.
thanks,
greg k-h
On Thu, Dec 10, 2020 at 01:45:19PM +0100, Greg KH wrote:
The less "special" steps I have to make, the less chance I mess something up :)
I've queued these up now, please check that I got it right.
Perfect, thank you. I'll follow up with a respin of the bcm2835aux patch.
Lukas
On Thu, Dec 10, 2020 at 05:13:36PM +0100, Lukas Wunner wrote:
On Thu, Dec 10, 2020 at 01:45:19PM +0100, Greg KH wrote:
The less "special" steps I have to make, the less chance I mess something up :)
I've queued these up now, please check that I got it right.
Perfect, thank you. I'll follow up with a respin of the bcm2835aux patch.
Okay I've just sent out a series consisting of 2 patches. That series applies cleanly to all of 4.19, 4.14, 4.9 and 4.4-stable.
Thanks,
Lukas
From: Peter Ujfalusi peter.ujfalusi@ti.com
[ Upstream commit 666224b43b4bd4612ce3b758c038f9bc5c5e3fcb ]
The DMA channel was not released if either devm_request_irq() or devm_spi_register_controller() failed.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com Reviewed-by: Nicolas Saenz Julienne nsaenzjulienne@suse.de Link: https://lore.kernel.org/r/20191212135550.4634-3-peter.ujfalusi@ti.com Signed-off-by: Mark Brown broonie@kernel.org [lukas: backport to 4.19-stable] Signed-off-by: Lukas Wunner lukas@wunner.de --- drivers/spi/spi-bcm2835.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index 2908df35466f..6824beae18e4 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -787,18 +787,19 @@ static int bcm2835_spi_probe(struct platform_device *pdev) dev_name(&pdev->dev), master); if (err) { dev_err(&pdev->dev, "could not request IRQ: %d\n", err); - goto out_clk_disable; + goto out_dma_release; }
err = spi_register_master(master); if (err) { dev_err(&pdev->dev, "could not register SPI master: %d\n", err); - goto out_clk_disable; + goto out_dma_release; }
return 0;
-out_clk_disable: +out_dma_release: + bcm2835_dma_release(master); clk_disable_unprepare(bs->clk); return err; }
linux-stable-mirror@lists.linaro.org