From 47ad9e5b563e07abb5f5ee0139970aad09ceb8ff Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 14 Dec 2020 16:47:26 +0100 Subject: [PATCH] 4.9-stable patches added patches: spi-prevent-adding-devices-below-an-unregistering-controller.patch --- queue-4.9/series | 1 + ...es-below-an-unregistering-controller.patch | 110 ++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 queue-4.9/spi-prevent-adding-devices-below-an-unregistering-controller.patch diff --git a/queue-4.9/series b/queue-4.9/series index 4ccb7f48d00..ca7aadab58e 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -8,3 +8,4 @@ input-cm109-do-not-stomp-on-control-urb.patch input-i8042-add-acer-laptops-to-the-i8042-reset-list.patch pinctrl-amd-remove-debounce-filter-setting-in-irq-type-setting.patch scsi-be2iscsi-revert-fix-a-theoretical-leak-in-beiscsi_create_eqs.patch +spi-prevent-adding-devices-below-an-unregistering-controller.patch diff --git a/queue-4.9/spi-prevent-adding-devices-below-an-unregistering-controller.patch b/queue-4.9/spi-prevent-adding-devices-below-an-unregistering-controller.patch new file mode 100644 index 00000000000..da4f10fd989 --- /dev/null +++ b/queue-4.9/spi-prevent-adding-devices-below-an-unregistering-controller.patch @@ -0,0 +1,110 @@ +From foo@baz Mon Dec 14 04:45:35 PM CET 2020 +From: Lukas Wunner +Date: Mon, 3 Aug 2020 13:09:01 +0200 +Subject: spi: Prevent adding devices below an unregistering controller + +From: Lukas Wunner + +commit ddf75be47ca748f8b12d28ac64d624354fddf189 upstream + +CONFIG_OF_DYNAMIC and CONFIG_ACPI allow adding SPI devices at runtime +using a DeviceTree overlay or DSDT patch. CONFIG_SPI_SLAVE allows the +same via sysfs. + +But there are no precautions to prevent adding a device below a +controller that's being removed. Such a device is unusable and may not +even be able to unbind cleanly as it becomes inaccessible once the +controller has been torn down. E.g. it is then impossible to quiesce +the device's interrupt. + +of_spi_notify() and acpi_spi_notify() do hold a ref on the controller, +but otherwise run lockless against spi_unregister_controller(). + +Fix by holding the spi_add_lock in spi_unregister_controller() and +bailing out of spi_add_device() if the controller has been unregistered +concurrently. + +Fixes: ce79d54ae447 ("spi/of: Add OF notifier handler") +Signed-off-by: Lukas Wunner +Cc: stable@vger.kernel.org # v3.19+ +Cc: Geert Uytterhoeven +Cc: Octavian Purdila +Cc: Pantelis Antoniou +Link: https://lore.kernel.org/r/a8c3205088a969dc8410eec1eba9aface60f36af.1596451035.git.lukas@wunner.de +Signed-off-by: Mark Brown +[sudip: adjust context] +Signed-off-by: Sudip Mukherjee +Signed-off-by: Greg Kroah-Hartman +--- + drivers/spi/Kconfig | 3 +++ + drivers/spi/spi.c | 21 ++++++++++++++++++++- + 2 files changed, 23 insertions(+), 1 deletion(-) + +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -763,4 +763,7 @@ endif # SPI_MASTER + + # (slave support would go here) + ++config SPI_DYNAMIC ++ def_bool ACPI || OF_DYNAMIC || SPI_SLAVE ++ + endif # SPI +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -422,6 +422,12 @@ static LIST_HEAD(spi_master_list); + */ + static DEFINE_MUTEX(board_lock); + ++/* ++ * Prevents addition of devices with same chip select and ++ * addition of devices below an unregistering controller. ++ */ ++static DEFINE_MUTEX(spi_add_lock); ++ + /** + * spi_alloc_device - Allocate a new SPI device + * @master: Controller to which device is connected +@@ -500,7 +506,6 @@ static int spi_dev_check(struct device * + */ + int spi_add_device(struct spi_device *spi) + { +- static DEFINE_MUTEX(spi_add_lock); + struct spi_master *master = spi->master; + struct device *dev = master->dev.parent; + int status; +@@ -529,6 +534,13 @@ int spi_add_device(struct spi_device *sp + goto done; + } + ++ /* Controller may unregister concurrently */ ++ if (IS_ENABLED(CONFIG_SPI_DYNAMIC) && ++ !device_is_registered(&master->dev)) { ++ status = -ENODEV; ++ goto done; ++ } ++ + if (master->cs_gpios) + spi->cs_gpio = master->cs_gpios[spi->chip_select]; + +@@ -2070,6 +2082,10 @@ static int __unregister(struct device *d + */ + void spi_unregister_master(struct spi_master *master) + { ++ /* Prevent addition of new devices, unregister existing ones */ ++ if (IS_ENABLED(CONFIG_SPI_DYNAMIC)) ++ mutex_lock(&spi_add_lock); ++ + device_for_each_child(&master->dev, NULL, __unregister); + + if (master->queued) { +@@ -2089,6 +2105,9 @@ void spi_unregister_master(struct spi_ma + if (!devres_find(master->dev.parent, devm_spi_release_master, + devm_spi_match_master, master)) + put_device(&master->dev); ++ ++ if (IS_ENABLED(CONFIG_SPI_DYNAMIC)) ++ mutex_unlock(&spi_add_lock); + } + EXPORT_SYMBOL_GPL(spi_unregister_master); + -- 2.47.3