Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'spi-fix-v7.0-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi

Pull spi fixes from Mark Brown:
"There are two core fixes here. One is from Johan dealing with an issue
introduced by a devm_ API usage update causing things to be freed
earlier than they had earlier when we fail to register a device,
another from Danilo avoids unlocked acccess to data by converting to
use a driver core API.

We also have a few relatively minor driver specific fixes"

* tag 'spi-fix-v7.0-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
spi: spi-fsl-lpspi: fix teardown order issue (UAF)
spi: fix use-after-free on managed registration failure
spi: use generic driver_override infrastructure
spi: meson-spicc: Fix double-put in remove path
spi: sn-f-ospi: Use devm_mutex_init() to simplify code
spi: sn-f-ospi: Fix resource leak in f_ospi_probe()

+31 -53
+2 -1
drivers/spi/spi-fsl-lpspi.c
··· 1009 1009 enable_irq(irq); 1010 1010 } 1011 1011 1012 - ret = devm_spi_register_controller(&pdev->dev, controller); 1012 + ret = spi_register_controller(controller); 1013 1013 if (ret < 0) { 1014 1014 dev_err_probe(&pdev->dev, ret, "spi_register_controller error\n"); 1015 1015 goto free_dma; ··· 1035 1035 struct fsl_lpspi_data *fsl_lpspi = 1036 1036 spi_controller_get_devdata(controller); 1037 1037 1038 + spi_unregister_controller(controller); 1038 1039 fsl_lpspi_dma_exit(controller); 1039 1040 1040 1041 pm_runtime_dont_use_autosuspend(fsl_lpspi->dev);
-2
drivers/spi/spi-meson-spicc.c
··· 1101 1101 1102 1102 /* Disable SPI */ 1103 1103 writel(0, spicc->base + SPICC_CONREG); 1104 - 1105 - spi_controller_put(spicc->host); 1106 1104 } 1107 1105 1108 1106 static const struct meson_spicc_data meson_spicc_gx_data = {
+10 -32
drivers/spi/spi-sn-f-ospi.c
··· 612 612 u32 num_cs = OSPI_NUM_CS; 613 613 int ret; 614 614 615 - ctlr = spi_alloc_host(dev, sizeof(*ospi)); 615 + ctlr = devm_spi_alloc_host(dev, sizeof(*ospi)); 616 616 if (!ctlr) 617 617 return -ENOMEM; 618 618 ··· 635 635 platform_set_drvdata(pdev, ospi); 636 636 637 637 ospi->base = devm_platform_ioremap_resource(pdev, 0); 638 - if (IS_ERR(ospi->base)) { 639 - ret = PTR_ERR(ospi->base); 640 - goto err_put_ctlr; 641 - } 638 + if (IS_ERR(ospi->base)) 639 + return PTR_ERR(ospi->base); 642 640 643 641 ospi->clk = devm_clk_get_enabled(dev, NULL); 644 - if (IS_ERR(ospi->clk)) { 645 - ret = PTR_ERR(ospi->clk); 646 - goto err_put_ctlr; 647 - } 642 + if (IS_ERR(ospi->clk)) 643 + return PTR_ERR(ospi->clk); 648 644 649 - mutex_init(&ospi->mlock); 645 + ret = devm_mutex_init(dev, &ospi->mlock); 646 + if (ret) 647 + return ret; 650 648 651 649 ret = f_ospi_init(ospi); 652 650 if (ret) 653 - goto err_destroy_mutex; 651 + return ret; 654 652 655 - ret = devm_spi_register_controller(dev, ctlr); 656 - if (ret) 657 - goto err_destroy_mutex; 658 - 659 - return 0; 660 - 661 - err_destroy_mutex: 662 - mutex_destroy(&ospi->mlock); 663 - 664 - err_put_ctlr: 665 - spi_controller_put(ctlr); 666 - 667 - return ret; 668 - } 669 - 670 - static void f_ospi_remove(struct platform_device *pdev) 671 - { 672 - struct f_ospi *ospi = platform_get_drvdata(pdev); 673 - 674 - mutex_destroy(&ospi->mlock); 653 + return devm_spi_register_controller(dev, ctlr); 675 654 } 676 655 677 656 static const struct of_device_id f_ospi_dt_ids[] = { ··· 665 686 .of_match_table = f_ospi_dt_ids, 666 687 }, 667 688 .probe = f_ospi_probe, 668 - .remove = f_ospi_remove, 669 689 }; 670 690 module_platform_driver(f_ospi_driver); 671 691
+19 -13
drivers/spi/spi.c
··· 50 50 struct spi_device *spi = to_spi_device(dev); 51 51 52 52 spi_controller_put(spi->controller); 53 - kfree(spi->driver_override); 54 53 free_percpu(spi->pcpu_statistics); 55 54 kfree(spi); 56 55 } ··· 72 73 struct device_attribute *a, 73 74 const char *buf, size_t count) 74 75 { 75 - struct spi_device *spi = to_spi_device(dev); 76 76 int ret; 77 77 78 - ret = driver_set_override(dev, &spi->driver_override, buf, count); 78 + ret = __device_set_driver_override(dev, buf, count); 79 79 if (ret) 80 80 return ret; 81 81 ··· 84 86 static ssize_t driver_override_show(struct device *dev, 85 87 struct device_attribute *a, char *buf) 86 88 { 87 - const struct spi_device *spi = to_spi_device(dev); 88 - ssize_t len; 89 - 90 - device_lock(dev); 91 - len = sysfs_emit(buf, "%s\n", spi->driver_override ? : ""); 92 - device_unlock(dev); 93 - return len; 89 + guard(spinlock)(&dev->driver_override.lock); 90 + return sysfs_emit(buf, "%s\n", dev->driver_override.name ?: ""); 94 91 } 95 92 static DEVICE_ATTR_RW(driver_override); 96 93 ··· 369 376 { 370 377 const struct spi_device *spi = to_spi_device(dev); 371 378 const struct spi_driver *sdrv = to_spi_driver(drv); 379 + int ret; 372 380 373 381 /* Check override first, and if set, only use the named driver */ 374 - if (spi->driver_override) 375 - return strcmp(spi->driver_override, drv->name) == 0; 382 + ret = device_match_driver_override(dev, drv); 383 + if (ret >= 0) 384 + return ret; 376 385 377 386 /* Attempt an OF style match */ 378 387 if (of_driver_match_device(dev, drv)) ··· 3534 3539 if (ret) 3535 3540 return ret; 3536 3541 3537 - return devm_add_action_or_reset(dev, devm_spi_unregister_controller, ctlr); 3542 + /* 3543 + * Prevent controller from being freed by spi_unregister_controller() 3544 + * if devm_add_action_or_reset() fails for a non-devres allocated 3545 + * controller. 3546 + */ 3547 + spi_controller_get(ctlr); 3538 3548 3549 + ret = devm_add_action_or_reset(dev, devm_spi_unregister_controller, ctlr); 3550 + 3551 + if (ret == 0 || ctlr->devm_allocated) 3552 + spi_controller_put(ctlr); 3553 + 3554 + return ret; 3539 3555 } 3540 3556 EXPORT_SYMBOL_GPL(devm_spi_register_controller); 3541 3557
-5
include/linux/spi/spi.h
··· 159 159 * @modalias: Name of the driver to use with this device, or an alias 160 160 * for that name. This appears in the sysfs "modalias" attribute 161 161 * for driver coldplugging, and in uevents used for hotplugging 162 - * @driver_override: If the name of a driver is written to this attribute, then 163 - * the device will bind to the named driver and only the named driver. 164 - * Do not set directly, because core frees it; use driver_set_override() to 165 - * set or clear it. 166 162 * @pcpu_statistics: statistics for the spi_device 167 163 * @word_delay: delay to be inserted between consecutive 168 164 * words of a transfer ··· 220 224 void *controller_state; 221 225 void *controller_data; 222 226 char modalias[SPI_NAME_SIZE]; 223 - const char *driver_override; 224 227 225 228 /* The statistics */ 226 229 struct spi_statistics __percpu *pcpu_statistics;