From 1a8eddd0915f5e5e1c4bf1abde2790d5ee773564 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 10 Dec 2020 13:44:49 +0100 Subject: [PATCH] 4.4-stable patches added patches: iommu-amd-set-dte-to-represent-512-irtes.patch spi-bcm2835-fix-use-after-free-on-unbind.patch spi-bcm2835-release-the-dma-channel-if-probe-fails-after-dma_init.patch spi-introduce-device-managed-spi-controller-allocation.patch --- ...u-amd-set-dte-to-represent-512-irtes.patch | 36 +++++ queue-4.4/series | 4 + ...bcm2835-fix-use-after-free-on-unbind.patch | 83 ++++++++++ ...hannel-if-probe-fails-after-dma_init.patch | 51 ++++++ ...ce-managed-spi-controller-allocation.patch | 149 ++++++++++++++++++ 5 files changed, 323 insertions(+) create mode 100644 queue-4.4/iommu-amd-set-dte-to-represent-512-irtes.patch create mode 100644 queue-4.4/spi-bcm2835-fix-use-after-free-on-unbind.patch create mode 100644 queue-4.4/spi-bcm2835-release-the-dma-channel-if-probe-fails-after-dma_init.patch create mode 100644 queue-4.4/spi-introduce-device-managed-spi-controller-allocation.patch diff --git a/queue-4.4/iommu-amd-set-dte-to-represent-512-irtes.patch b/queue-4.4/iommu-amd-set-dte-to-represent-512-irtes.patch new file mode 100644 index 00000000000..77f53d1fdd7 --- /dev/null +++ b/queue-4.4/iommu-amd-set-dte-to-represent-512-irtes.patch @@ -0,0 +1,36 @@ +From 4165bf015ba9454f45beaad621d16c516d5c5afe Mon Sep 17 00:00:00 2001 +From: Suravee Suthikulpanit +Date: Mon, 7 Dec 2020 03:19:20 -0600 +Subject: iommu/amd: Set DTE[IntTabLen] to represent 512 IRTEs + +From: Suravee Suthikulpanit + +commit 4165bf015ba9454f45beaad621d16c516d5c5afe upstream. + +According to the AMD IOMMU spec, the commit 73db2fc595f3 +("iommu/amd: Increase interrupt remapping table limit to 512 entries") +also requires the interrupt table length (IntTabLen) to be set to 9 +(power of 2) in the device table mapping entry (DTE). + +Fixes: 73db2fc595f3 ("iommu/amd: Increase interrupt remapping table limit to 512 entries") +Reported-by: Jerry Snitselaar +Signed-off-by: Suravee Suthikulpanit +Reviewed-by: Jerry Snitselaar +Link: https://lore.kernel.org/r/20201207091920.3052-1-suravee.suthikulpanit@amd.com +Signed-off-by: Will Deacon +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iommu/amd_iommu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/iommu/amd_iommu.c ++++ b/drivers/iommu/amd_iommu.c +@@ -3625,7 +3625,7 @@ static struct irq_chip amd_ir_chip; + + #define DTE_IRQ_PHYS_ADDR_MASK (((1ULL << 45)-1) << 6) + #define DTE_IRQ_REMAP_INTCTL (2ULL << 60) +-#define DTE_IRQ_TABLE_LEN (8ULL << 1) ++#define DTE_IRQ_TABLE_LEN (9ULL << 1) + #define DTE_IRQ_REMAP_ENABLE 1ULL + + static void set_dte_irq_entry(u16 devid, struct irq_remap_table *table) diff --git a/queue-4.4/series b/queue-4.4/series index f2addd25266..8c96e7d8eb5 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -27,3 +27,7 @@ cifs-fix-potential-use-after-free-in-cifs_echo_request.patch i2c-imx-fix-reset-of-i2sr_ial-flag.patch i2c-imx-check-for-i2sr_ial-after-every-byte.patch arm64-assembler-make-adr_l-work-in-modules-under-kaslr.patch +iommu-amd-set-dte-to-represent-512-irtes.patch +spi-introduce-device-managed-spi-controller-allocation.patch +spi-bcm2835-fix-use-after-free-on-unbind.patch +spi-bcm2835-release-the-dma-channel-if-probe-fails-after-dma_init.patch diff --git a/queue-4.4/spi-bcm2835-fix-use-after-free-on-unbind.patch b/queue-4.4/spi-bcm2835-fix-use-after-free-on-unbind.patch new file mode 100644 index 00000000000..4a2abe300de --- /dev/null +++ b/queue-4.4/spi-bcm2835-fix-use-after-free-on-unbind.patch @@ -0,0 +1,83 @@ +From foo@baz Thu Dec 10 01:43:58 PM CET 2020 +From: Lukas Wunner +Date: Sun, 6 Dec 2020 13:53:01 +0100 +Subject: spi: bcm2835: Fix use-after-free on unbind +To: Greg Kroah-Hartman +Cc: Mark Brown , Sudip Mukherjee , stable@vger.kernel.org +Message-ID: <196d7c6ce1a7f6bb81ea6c13d94acba7c15cf473.1607259026.git.lukas@wunner.de> + +From: Lukas Wunner + +[ 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 +Reported-by: Florian Fainelli +Signed-off-by: Lukas Wunner +Cc: # v3.10+: 5e844cc37a5c: spi: Introduce device-managed SPI controller allocation +Cc: # v3.10+ +Cc: Vladimir Oltean +Tested-by: Florian Fainelli +Acked-by: Florian Fainelli +Link: https://lore.kernel.org/r/ad66e0a0ad96feb848814842ecf5b6a4539ef35c.1605121038.git.lukas@wunner.de +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + drivers/spi/spi-bcm2835.c | 15 +++++---------- + 1 file changed, 5 insertions(+), 10 deletions(-) + +--- a/drivers/spi/spi-bcm2835.c ++++ b/drivers/spi/spi-bcm2835.c +@@ -742,7 +742,7 @@ static int bcm2835_spi_probe(struct plat + 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; +@@ -764,23 +764,20 @@ static int bcm2835_spi_probe(struct plat + + 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); +@@ -808,8 +805,6 @@ static int bcm2835_spi_probe(struct plat + + out_clk_disable: + clk_disable_unprepare(bs->clk); +-out_master_put: +- spi_master_put(master); + return err; + } + diff --git a/queue-4.4/spi-bcm2835-release-the-dma-channel-if-probe-fails-after-dma_init.patch b/queue-4.4/spi-bcm2835-release-the-dma-channel-if-probe-fails-after-dma_init.patch new file mode 100644 index 00000000000..d1781bbade3 --- /dev/null +++ b/queue-4.4/spi-bcm2835-release-the-dma-channel-if-probe-fails-after-dma_init.patch @@ -0,0 +1,51 @@ +From foo@baz Thu Dec 10 01:43:58 PM CET 2020 +From: Lukas Wunner +Date: Sun, 6 Dec 2020 13:53:03 +0100 +Subject: spi: bcm2835: Release the DMA channel if probe fails after dma_init +To: Greg Kroah-Hartman +Cc: Mark Brown , Sudip Mukherjee , stable@vger.kernel.org +Message-ID: <7682937f1bf3e06319e8048c9e0e61a6ea62256c.1607259026.git.lukas@wunner.de> + +From: Peter Ujfalusi + +[ 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 +Reviewed-by: Nicolas Saenz Julienne +Link: https://lore.kernel.org/r/20191212135550.4634-3-peter.ujfalusi@ti.com +Signed-off-by: Mark Brown +[lukas: backport to 4.19-stable] +Signed-off-by: Lukas Wunner +Signed-off-by: Greg Kroah-Hartman +--- + drivers/spi/spi-bcm2835.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/spi/spi-bcm2835.c ++++ b/drivers/spi/spi-bcm2835.c +@@ -792,18 +792,19 @@ static int bcm2835_spi_probe(struct plat + 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; + } diff --git a/queue-4.4/spi-introduce-device-managed-spi-controller-allocation.patch b/queue-4.4/spi-introduce-device-managed-spi-controller-allocation.patch new file mode 100644 index 00000000000..e5e7f8deba2 --- /dev/null +++ b/queue-4.4/spi-introduce-device-managed-spi-controller-allocation.patch @@ -0,0 +1,149 @@ +From foo@baz Thu Dec 10 01:43:58 PM CET 2020 +From: Lukas Wunner +Date: Sun, 6 Dec 2020 13:53:00 +0100 +Subject: spi: Introduce device-managed SPI controller allocation +To: Greg Kroah-Hartman +Cc: Mark Brown , Sudip Mukherjee , stable@vger.kernel.org +Message-ID: + +From: Lukas Wunner + +[ Upstream commit 5e844cc37a5cbaa460e68f9a989d321d63088a89 ] + +SPI driver probing currently comprises two steps, whereas removal +comprises only one step: + + spi_alloc_master() + spi_register_master() + + spi_unregister_master() + +That's because spi_unregister_master() calls device_unregister() +instead of device_del(), thereby releasing the reference on the +spi_master which was obtained by spi_alloc_master(). + +An SPI driver's private data is contained in the same memory allocation +as the spi_master struct. Thus, once spi_unregister_master() has been +called, the private data is inaccessible. But some drivers need to +access it after spi_unregister_master() to perform further teardown +steps. + +Introduce devm_spi_alloc_master(), which releases a reference on the +spi_master struct only after the driver has unbound, thereby keeping the +memory allocation accessible. Change spi_unregister_master() to not +release a reference if the spi_master was allocated by the new devm +function. + +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_master in the probe error path. + +Long-term, most SPI drivers shall be moved over to the devm function +introduced herein. The few that can't shall be changed in a treewide +commit to explicitly release the last reference on the master. +That commit shall amend spi_unregister_master() 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 +Link: https://lore.kernel.org/r/272bae2ef08abd21388c98e23729886663d19192.1605121038.git.lukas@wunner.de +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + drivers/spi/spi.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++- + include/linux/spi/spi.h | 2 + + 2 files changed, 55 insertions(+), 1 deletion(-) + +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -1720,6 +1720,46 @@ struct spi_master *spi_alloc_master(stru + } + EXPORT_SYMBOL_GPL(spi_alloc_master); + ++static void devm_spi_release_master(struct device *dev, void *master) ++{ ++ spi_master_put(*(struct spi_master **)master); ++} ++ ++/** ++ * devm_spi_alloc_master - resource-managed spi_alloc_master() ++ * @dev: physical device of SPI master ++ * @size: how much zeroed driver-private data to allocate ++ * Context: can sleep ++ * ++ * Allocate an SPI master and automatically release a reference on it ++ * when @dev is unbound from its driver. Drivers are thus relieved from ++ * having to call spi_master_put(). ++ * ++ * The arguments to this function are identical to spi_alloc_master(). ++ * ++ * Return: the SPI master structure on success, else NULL. ++ */ ++struct spi_master *devm_spi_alloc_master(struct device *dev, unsigned int size) ++{ ++ struct spi_master **ptr, *master; ++ ++ ptr = devres_alloc(devm_spi_release_master, sizeof(*ptr), ++ GFP_KERNEL); ++ if (!ptr) ++ return NULL; ++ ++ master = spi_alloc_master(dev, size); ++ if (master) { ++ *ptr = master; ++ devres_add(dev, ptr); ++ } else { ++ devres_free(ptr); ++ } ++ ++ return master; ++} ++EXPORT_SYMBOL_GPL(devm_spi_alloc_master); ++ + #ifdef CONFIG_OF + static int of_spi_register_master(struct spi_master *master) + { +@@ -1899,6 +1939,11 @@ int devm_spi_register_master(struct devi + } + EXPORT_SYMBOL_GPL(devm_spi_register_master); + ++static int devm_spi_match_master(struct device *dev, void *res, void *master) ++{ ++ return *(struct spi_master **)res == master; ++} ++ + static int __unregister(struct device *dev, void *null) + { + spi_unregister_device(to_spi_device(dev)); +@@ -1928,7 +1973,14 @@ void spi_unregister_master(struct spi_ma + list_del(&master->list); + mutex_unlock(&board_lock); + +- device_unregister(&master->dev); ++ device_del(&master->dev); ++ ++ /* Release the last reference on the master if its driver ++ * has not yet been converted to devm_spi_alloc_master(). ++ */ ++ if (!devres_find(master->dev.parent, devm_spi_release_master, ++ devm_spi_match_master, master)) ++ put_device(&master->dev); + } + EXPORT_SYMBOL_GPL(spi_unregister_master); + +--- a/include/linux/spi/spi.h ++++ b/include/linux/spi/spi.h +@@ -568,6 +568,8 @@ extern void spi_finalize_current_transfe + /* the spi driver core manages memory for the spi_master classdev */ + extern struct spi_master * + spi_alloc_master(struct device *host, unsigned size); ++extern struct spi_master * ++devm_spi_alloc_master(struct device *dev, unsigned int size); + + extern int spi_register_master(struct spi_master *master); + extern int devm_spi_register_master(struct device *dev, -- 2.47.3