--- /dev/null
+From 67992ad376bc46d089047847329fd68105779f88 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jun 2020 15:05:01 +0800
+Subject: crypto: virtio: Fix dest length calculation in
+ __virtio_crypto_skcipher_do_req()
+
+From: Longpeng(Mike) <longpeng2@huawei.com>
+
+[ Upstream commit d90ca42012db2863a9a30b564a2ace6016594bda ]
+
+The src/dst length is not aligned with AES_BLOCK_SIZE(which is 16) in some
+testcases in tcrypto.ko.
+
+For example, the src/dst length of one of cts(cbc(aes))'s testcase is 17, the
+crypto_virtio driver will set @src_data_len=16 but @dst_data_len=17 in this
+case and get a wrong at then end.
+
+ SRC: pp pp pp pp pp pp pp pp pp pp pp pp pp pp pp pp pp (17 bytes)
+ EXP: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc pp (17 bytes)
+ DST: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc 00 (pollute the last bytes)
+ (pp: plaintext cc:ciphertext)
+
+Fix this issue by limit the length of dest buffer.
+
+Fixes: dbaf0624ffa5 ("crypto: add virtio-crypto driver")
+Cc: Gonglei <arei.gonglei@huawei.com>
+Cc: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: "Michael S. Tsirkin" <mst@redhat.com>
+Cc: Jason Wang <jasowang@redhat.com>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: virtualization@lists.linux-foundation.org
+Cc: linux-kernel@vger.kernel.org
+Cc: stable@vger.kernel.org
+Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
+Link: https://lore.kernel.org/r/20200602070501.2023-4-longpeng2@huawei.com
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/virtio/virtio_crypto_algs.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/crypto/virtio/virtio_crypto_algs.c b/drivers/crypto/virtio/virtio_crypto_algs.c
+index fee78ec46bae..e6b889ce395e 100644
+--- a/drivers/crypto/virtio/virtio_crypto_algs.c
++++ b/drivers/crypto/virtio/virtio_crypto_algs.c
+@@ -411,6 +411,7 @@ __virtio_crypto_ablkcipher_do_req(struct virtio_crypto_sym_request *vc_sym_req,
+ goto free;
+ }
+
++ dst_len = min_t(unsigned int, req->nbytes, dst_len);
+ pr_debug("virtio_crypto: src_len: %u, dst_len: %llu\n",
+ req->nbytes, dst_len);
+
+--
+2.25.1
+
--- /dev/null
+From 09b3038f723957bad01a80a59bf6ca16565a0c4c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jun 2020 15:04:59 +0800
+Subject: crypto: virtio: Fix src/dst scatterlist calculation in
+ __virtio_crypto_skcipher_do_req()
+
+From: Longpeng(Mike) <longpeng2@huawei.com>
+
+[ Upstream commit b02989f37fc5e865ceeee9070907e4493b3a21e2 ]
+
+The system will crash when the users insmod crypto/tcrypt.ko with mode=38
+( testing "cts(cbc(aes))" ).
+
+Usually the next entry of one sg will be @sg@ + 1, but if this sg element
+is part of a chained scatterlist, it could jump to the start of a new
+scatterlist array. Fix it by sg_next() on calculation of src/dst
+scatterlist.
+
+Fixes: dbaf0624ffa5 ("crypto: add virtio-crypto driver")
+Reported-by: LABBE Corentin <clabbe@baylibre.com>
+Cc: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: "Michael S. Tsirkin" <mst@redhat.com>
+Cc: Jason Wang <jasowang@redhat.com>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: virtualization@lists.linux-foundation.org
+Cc: linux-kernel@vger.kernel.org
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20200123101000.GB24255@Red
+Signed-off-by: Gonglei <arei.gonglei@huawei.com>
+Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
+Link: https://lore.kernel.org/r/20200602070501.2023-2-longpeng2@huawei.com
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/virtio/virtio_crypto_algs.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/crypto/virtio/virtio_crypto_algs.c b/drivers/crypto/virtio/virtio_crypto_algs.c
+index 772d2b3137c6..fee78ec46bae 100644
+--- a/drivers/crypto/virtio/virtio_crypto_algs.c
++++ b/drivers/crypto/virtio/virtio_crypto_algs.c
+@@ -354,13 +354,18 @@ __virtio_crypto_ablkcipher_do_req(struct virtio_crypto_sym_request *vc_sym_req,
+ int err;
+ unsigned long flags;
+ struct scatterlist outhdr, iv_sg, status_sg, **sgs;
+- int i;
+ u64 dst_len;
+ unsigned int num_out = 0, num_in = 0;
+ int sg_total;
+ uint8_t *iv;
++ struct scatterlist *sg;
+
+ src_nents = sg_nents_for_len(req->src, req->nbytes);
++ if (src_nents < 0) {
++ pr_err("Invalid number of src SG.\n");
++ return src_nents;
++ }
++
+ dst_nents = sg_nents(req->dst);
+
+ pr_debug("virtio_crypto: Number of sgs (src_nents: %d, dst_nents: %d)\n",
+@@ -441,12 +446,12 @@ __virtio_crypto_ablkcipher_do_req(struct virtio_crypto_sym_request *vc_sym_req,
+ vc_sym_req->iv = iv;
+
+ /* Source data */
+- for (i = 0; i < src_nents; i++)
+- sgs[num_out++] = &req->src[i];
++ for (sg = req->src; src_nents; sg = sg_next(sg), src_nents--)
++ sgs[num_out++] = sg;
+
+ /* Destination data */
+- for (i = 0; i < dst_nents; i++)
+- sgs[num_out + num_in++] = &req->dst[i];
++ for (sg = req->dst; sg; sg = sg_next(sg))
++ sgs[num_out + num_in++] = sg;
+
+ /* Status */
+ sg_init_one(&status_sg, &vc_req->status, sizeof(vc_req->status));
+--
+2.25.1
+
--- /dev/null
+From e7405be90fb03776c6a744e137f2122dfcf41460 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jun 2020 15:05:00 +0800
+Subject: crypto: virtio: Fix use-after-free in
+ virtio_crypto_skcipher_finalize_req()
+
+From: Longpeng(Mike) <longpeng2@huawei.com>
+
+[ Upstream commit 8c855f0720ff006d75d0a2512c7f6c4f60ff60ee ]
+
+The system'll crash when the users insmod crypto/tcrypto.ko with mode=155
+( testing "authenc(hmac(sha1),cbc(aes))" ). It's caused by reuse the memory
+of request structure.
+
+In crypto_authenc_init_tfm(), the reqsize is set to:
+ [PART 1] sizeof(authenc_request_ctx) +
+ [PART 2] ictx->reqoff +
+ [PART 3] MAX(ahash part, skcipher part)
+and the 'PART 3' is used by both ahash and skcipher in turn.
+
+When the virtio_crypto driver finish skcipher req, it'll call ->complete
+callback(in crypto_finalize_skcipher_request) and then free its
+resources whose pointers are recorded in 'skcipher parts'.
+
+However, the ->complete is 'crypto_authenc_encrypt_done' in this case,
+it will use the 'ahash part' of the request and change its content,
+so virtio_crypto driver will get the wrong pointer after ->complete
+finish and mistakenly free some other's memory. So the system will crash
+when these memory will be used again.
+
+The resources which need to be cleaned up are not used any more. But the
+pointers of these resources may be changed in the function
+"crypto_finalize_skcipher_request". Thus release specific resources before
+calling this function.
+
+Fixes: dbaf0624ffa5 ("crypto: add virtio-crypto driver")
+Reported-by: LABBE Corentin <clabbe@baylibre.com>
+Cc: Gonglei <arei.gonglei@huawei.com>
+Cc: Herbert Xu <herbert@gondor.apana.org.au>
+Cc: "Michael S. Tsirkin" <mst@redhat.com>
+Cc: Jason Wang <jasowang@redhat.com>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: virtualization@lists.linux-foundation.org
+Cc: linux-kernel@vger.kernel.org
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20200123101000.GB24255@Red
+Acked-by: Gonglei <arei.gonglei@huawei.com>
+Signed-off-by: Longpeng(Mike) <longpeng2@huawei.com>
+Link: https://lore.kernel.org/r/20200602070501.2023-3-longpeng2@huawei.com
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/crypto/virtio/virtio_crypto_algs.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/crypto/virtio/virtio_crypto_algs.c b/drivers/crypto/virtio/virtio_crypto_algs.c
+index e2231a1a05a1..772d2b3137c6 100644
+--- a/drivers/crypto/virtio/virtio_crypto_algs.c
++++ b/drivers/crypto/virtio/virtio_crypto_algs.c
+@@ -569,10 +569,11 @@ static void virtio_crypto_ablkcipher_finalize_req(
+ struct ablkcipher_request *req,
+ int err)
+ {
+- crypto_finalize_cipher_request(vc_sym_req->base.dataq->engine,
+- req, err);
+ kzfree(vc_sym_req->iv);
+ virtcrypto_clear_request(&vc_sym_req->base);
++
++ crypto_finalize_cipher_request(vc_sym_req->base.dataq->engine,
++ req, err);
+ }
+
+ static struct crypto_alg virtio_crypto_algs[] = { {
+--
+2.25.1
+
x86-speculation-add-support-for-stibp-always-on-pref.patch
x86-speculation-avoid-force-disabling-ibpb-based-on-.patch
x86-speculation-pr_spec_force_disable-enforcement-fo.patch
+spi-dw-fix-possible-race-condition.patch
+spi-dw-fix-controller-unregister-order.patch
+spi-no-need-to-assign-dummy-value-in-spi_unregister_.patch
+spi-fix-controller-unregister-order.patch
+spi-pxa2xx-fix-controller-unregister-order.patch
+spi-bcm2835-fix-controller-unregister-order.patch
+crypto-virtio-fix-use-after-free-in-virtio_crypto_sk.patch
+crypto-virtio-fix-src-dst-scatterlist-calculation-in.patch
+crypto-virtio-fix-dest-length-calculation-in-__virti.patch
--- /dev/null
+From 7575d6e0d4ee2629850b412630a613fee59d5a3e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 May 2020 17:58:02 +0200
+Subject: spi: bcm2835: Fix controller unregister order
+
+From: Lukas Wunner <lukas@wunner.de>
+
+[ Upstream commit 9dd277ff92d06f6aa95b39936ad83981d781f49b ]
+
+The BCM2835 SPI driver uses devm_spi_register_controller() on bind.
+As a consequence, on unbind, __device_release_driver() first invokes
+bcm2835_spi_remove() before unregistering the SPI controller via
+devres_release_all().
+
+This order is incorrect: bcm2835_spi_remove() tears down the DMA
+channels and turns off the SPI controller, including its interrupts
+and clock. The SPI controller is thus no longer usable.
+
+When the SPI controller is subsequently unregistered, it unbinds all
+its slave devices. If their drivers need to access the SPI bus,
+e.g. to quiesce their interrupts, unbinding will fail.
+
+As a rule, devm_spi_register_controller() must not be used if the
+->remove() hook performs teardown steps which shall be performed
+after unbinding of slaves.
+
+Fix by using the non-devm variant spi_register_controller(). Note that
+the struct spi_controller as well as the driver-private data are not
+freed until after bcm2835_spi_remove() has finished, so accessing them
+is safe.
+
+Fixes: 247263dba208 ("spi: bcm2835: use devm_spi_register_master()")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: stable@vger.kernel.org # v3.13+
+Link: https://lore.kernel.org/r/2397dd70cdbe95e0bc4da2b9fca0f31cb94e5aed.1589557526.git.lukas@wunner.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-bcm2835.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c
+index eab27d41ba83..df6abc75bc16 100644
+--- a/drivers/spi/spi-bcm2835.c
++++ b/drivers/spi/spi-bcm2835.c
+@@ -793,7 +793,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
+ goto out_clk_disable;
+ }
+
+- err = devm_spi_register_master(&pdev->dev, master);
++ err = spi_register_master(master);
+ if (err) {
+ dev_err(&pdev->dev, "could not register SPI master: %d\n", err);
+ goto out_clk_disable;
+@@ -813,6 +813,8 @@ static int bcm2835_spi_remove(struct platform_device *pdev)
+ struct spi_master *master = platform_get_drvdata(pdev);
+ struct bcm2835_spi *bs = spi_master_get_devdata(master);
+
++ spi_unregister_master(master);
++
+ /* Clear FIFOs, and disable the HW block */
+ bcm2835_wr(bs, BCM2835_SPI_CS,
+ BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX);
+--
+2.25.1
+
--- /dev/null
+From 4d5c7d2ae41eff29f8871931e22d00d93ceb3744 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2020 14:25:01 +0200
+Subject: spi: dw: Fix controller unregister order
+
+From: Lukas Wunner <lukas@wunner.de>
+
+[ Upstream commit ca8b19d61e3fce5d2d7790cde27a0b57bcb3f341 ]
+
+The Designware SPI driver uses devm_spi_register_controller() on bind.
+As a consequence, on unbind, __device_release_driver() first invokes
+dw_spi_remove_host() before unregistering the SPI controller via
+devres_release_all().
+
+This order is incorrect: dw_spi_remove_host() shuts down the chip,
+rendering the SPI bus inaccessible even though the SPI controller is
+still registered. When the SPI controller is subsequently unregistered,
+it unbinds all its slave devices. Because their drivers cannot access
+the SPI bus, e.g. to quiesce interrupts, the slave devices may be left
+in an improper state.
+
+As a rule, devm_spi_register_controller() must not be used if the
+->remove() hook performs teardown steps which shall be performed after
+unregistering the controller and specifically after unbinding of slaves.
+
+Fix by reverting to the non-devm variant of spi_register_controller().
+
+An alternative approach would be to use device-managed functions for all
+steps in dw_spi_remove_host(), e.g. by calling devm_add_action_or_reset()
+on probe. However that approach would add more LoC to the driver and
+it wouldn't lend itself as well to backporting to stable.
+
+Fixes: 04f421e7b0b1 ("spi: dw: use managed resources")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Cc: stable@vger.kernel.org # v3.14+
+Cc: Baruch Siach <baruch@tkos.co.il>
+Link: https://lore.kernel.org/r/3fff8cb8ae44a9893840d0688be15bb88c090a14.1590408496.git.lukas@wunner.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-dw.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c
+index 5c16f7b17029..b11d0cd3fd20 100644
+--- a/drivers/spi/spi-dw.c
++++ b/drivers/spi/spi-dw.c
+@@ -534,7 +534,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
+ }
+ }
+
+- ret = devm_spi_register_master(dev, master);
++ ret = spi_register_master(master);
+ if (ret) {
+ dev_err(&master->dev, "problem registering spi master\n");
+ goto err_dma_exit;
+@@ -558,6 +558,8 @@ void dw_spi_remove_host(struct dw_spi *dws)
+ {
+ dw_spi_debugfs_remove(dws);
+
++ spi_unregister_master(dws->master);
++
+ if (dws->dma_ops && dws->dma_ops->dma_exit)
+ dws->dma_ops->dma_exit(dws);
+
+--
+2.25.1
+
--- /dev/null
+From 6d1bebbf54ed2f9639cd829fac84a8562ed25a35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jun 2020 17:28:08 -0400
+Subject: spi: dw: fix possible race condition
+
+[ Upstream commit 66b19d762378785d1568b5650935205edfeb0503 ]
+
+It is possible to get an interrupt as soon as it is requested. dw_spi_irq
+does spi_controller_get_devdata(master) and expects it to be different than
+NULL. However, spi_controller_set_devdata() is called after request_irq(),
+resulting in the following crash:
+
+CPU 0 Unable to handle kernel paging request at virtual address 00000030, epc == 8058e09c, ra == 8018ff90
+[...]
+Call Trace:
+[<8058e09c>] dw_spi_irq+0x8/0x64
+[<8018ff90>] __handle_irq_event_percpu+0x70/0x1d4
+[<80190128>] handle_irq_event_percpu+0x34/0x8c
+[<801901c4>] handle_irq_event+0x44/0x80
+[<801951a8>] handle_level_irq+0xdc/0x194
+[<8018f580>] generic_handle_irq+0x38/0x50
+[<804c6924>] ocelot_irq_handler+0x104/0x1c0
+
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-dw.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c
+index cbdad3c4930f..5c16f7b17029 100644
+--- a/drivers/spi/spi-dw.c
++++ b/drivers/spi/spi-dw.c
+@@ -499,6 +499,8 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
+ dws->dma_addr = (dma_addr_t)(dws->paddr + DW_SPI_DR);
+ spin_lock_init(&dws->buf_lock);
+
++ spi_master_set_devdata(master, dws);
++
+ ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, dev_name(dev),
+ master);
+ if (ret < 0) {
+@@ -532,7 +534,6 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
+ }
+ }
+
+- spi_master_set_devdata(master, dws);
+ ret = devm_spi_register_master(dev, master);
+ if (ret) {
+ dev_err(&master->dev, "problem registering spi master\n");
+--
+2.25.1
+
--- /dev/null
+From dbac0fa2181b599a83e1c4d08368cf42c27bb75d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 May 2020 17:58:01 +0200
+Subject: spi: Fix controller unregister order
+
+From: Lukas Wunner <lukas@wunner.de>
+
+[ Upstream commit 84855678add8aba927faf76bc2f130a40f94b6f7 ]
+
+When an SPI controller unregisters, it unbinds all its slave devices.
+For this, their drivers may need to access the SPI bus, e.g. to quiesce
+interrupts.
+
+However since commit ffbbdd21329f ("spi: create a message queueing
+infrastructure"), spi_destroy_queue() is executed before unbinding the
+slaves. It sets ctlr->running = false, thereby preventing SPI bus
+access and causing unbinding of slave devices to fail.
+
+Fix by unbinding slaves before calling spi_destroy_queue().
+
+Fixes: ffbbdd21329f ("spi: create a message queueing infrastructure")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: stable@vger.kernel.org # v3.4+
+Cc: Linus Walleij <linus.walleij@linaro.org>
+Link: https://lore.kernel.org/r/8aaf9d44c153fe233b17bc2dec4eb679898d7e7b.1589557526.git.lukas@wunner.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
+index 8cc1b21d00d3..49eee894f51d 100644
+--- a/drivers/spi/spi.c
++++ b/drivers/spi/spi.c
+@@ -2265,6 +2265,8 @@ void spi_unregister_controller(struct spi_controller *ctlr)
+ struct spi_controller *found;
+ int id = ctlr->bus_num;
+
++ device_for_each_child(&ctlr->dev, NULL, __unregister);
++
+ /* First make sure that this controller was ever added */
+ mutex_lock(&board_lock);
+ found = idr_find(&spi_master_idr, id);
+@@ -2277,7 +2279,6 @@ void spi_unregister_controller(struct spi_controller *ctlr)
+ list_del(&ctlr->list);
+ mutex_unlock(&board_lock);
+
+- device_for_each_child(&ctlr->dev, NULL, __unregister);
+ device_unregister(&ctlr->dev);
+ /* free bus id */
+ mutex_lock(&board_lock);
+--
+2.25.1
+
--- /dev/null
+From 91c03f796d6fcc40d242eb7273749c4a6441f29f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 15 Jun 2019 20:41:35 +0300
+Subject: spi: No need to assign dummy value in spi_unregister_controller()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit ebc37af5e0a134355ea2b62ed4141458bdbd5389 ]
+
+The device_for_each_child() doesn't require the returned value to be checked.
+Thus, drop the dummy variable completely and have no warning anymore:
+
+drivers/spi/spi.c: In function ‘spi_unregister_controller’:
+drivers/spi/spi.c:2480:6: warning: variable ‘dummy’ set but not used [-Wunused-but-set-variable]
+ int dummy;
+ ^~~~~
+
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
+index 56035637d8f6..8cc1b21d00d3 100644
+--- a/drivers/spi/spi.c
++++ b/drivers/spi/spi.c
+@@ -2264,7 +2264,6 @@ void spi_unregister_controller(struct spi_controller *ctlr)
+ {
+ struct spi_controller *found;
+ int id = ctlr->bus_num;
+- int dummy;
+
+ /* First make sure that this controller was ever added */
+ mutex_lock(&board_lock);
+@@ -2278,7 +2277,7 @@ void spi_unregister_controller(struct spi_controller *ctlr)
+ list_del(&ctlr->list);
+ mutex_unlock(&board_lock);
+
+- dummy = device_for_each_child(&ctlr->dev, NULL, __unregister);
++ device_for_each_child(&ctlr->dev, NULL, __unregister);
+ device_unregister(&ctlr->dev);
+ /* free bus id */
+ mutex_lock(&board_lock);
+--
+2.25.1
+
--- /dev/null
+From 7871fb66c588fc3b9a10285cf61fbbf5cdd2b276 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 25 May 2020 14:25:02 +0200
+Subject: spi: pxa2xx: Fix controller unregister order
+
+From: Lukas Wunner <lukas@wunner.de>
+
+[ Upstream commit 32e5b57232c0411e7dea96625c415510430ac079 ]
+
+The PXA2xx SPI driver uses devm_spi_register_controller() on bind.
+As a consequence, on unbind, __device_release_driver() first invokes
+pxa2xx_spi_remove() before unregistering the SPI controller via
+devres_release_all().
+
+This order is incorrect: pxa2xx_spi_remove() disables the chip,
+rendering the SPI bus inaccessible even though the SPI controller is
+still registered. When the SPI controller is subsequently unregistered,
+it unbinds all its slave devices. Because their drivers cannot access
+the SPI bus, e.g. to quiesce interrupts, the slave devices may be left
+in an improper state.
+
+As a rule, devm_spi_register_controller() must not be used if the
+->remove() hook performs teardown steps which shall be performed after
+unregistering the controller and specifically after unbinding of slaves.
+
+Fix by reverting to the non-devm variant of spi_register_controller().
+
+An alternative approach would be to use device-managed functions for all
+steps in pxa2xx_spi_remove(), e.g. by calling devm_add_action_or_reset()
+on probe. However that approach would add more LoC to the driver and
+it wouldn't lend itself as well to backporting to stable.
+
+The improper use of devm_spi_register_controller() was introduced in 2013
+by commit a807fcd090d6 ("spi: pxa2xx: use devm_spi_register_master()"),
+but all earlier versions of the driver going back to 2006 were likewise
+broken because they invoked spi_unregister_master() at the end of
+pxa2xx_spi_remove(), rather than at the beginning.
+
+Fixes: e0c9905e87ac ("[PATCH] SPI: add PXA2xx SSP SPI Driver")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Cc: stable@vger.kernel.org # v2.6.17+
+Cc: Tsuchiya Yuto <kitakar@gmail.com>
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=206403#c1
+Link: https://lore.kernel.org/r/834c446b1cf3284d2660f1bee1ebe3e737cd02a9.1590408496.git.lukas@wunner.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-pxa2xx.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c
+index 5160e16d3a98..b73fde1de463 100644
+--- a/drivers/spi/spi-pxa2xx.c
++++ b/drivers/spi/spi-pxa2xx.c
+@@ -1826,7 +1826,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
+
+ /* Register with the SPI framework */
+ platform_set_drvdata(pdev, drv_data);
+- status = devm_spi_register_master(&pdev->dev, master);
++ status = spi_register_master(master);
+ if (status != 0) {
+ dev_err(&pdev->dev, "problem registering spi master\n");
+ goto out_error_clock_enabled;
+@@ -1856,6 +1856,8 @@ static int pxa2xx_spi_remove(struct platform_device *pdev)
+
+ pm_runtime_get_sync(&pdev->dev);
+
++ spi_unregister_master(drv_data->master);
++
+ /* Disable the SSP at the peripheral and SOC level */
+ pxa2xx_spi_write(drv_data, SSCR0, 0);
+ clk_disable_unprepare(ssp->clk);
+--
+2.25.1
+