Since commit 48720ba56891 ("virtio/s390: use DMA memory for ccw I/O and
classic notifiers") we were supposed to make sure that
virtio_ccw_release_dev() completes before the ccw device and the
attached dma pool are torn down, but unfortunately we did not. Before
that commit it used to be OK to delay cleaning up the memory allocated
by virtio-ccw indefinitely (which isn't really intuitive for guys used
to destruction happens in reverse construction order), but now we
trigger a BUG_ON if the genpool is destroyed before all memory allocated
form it. Which brings down the guest. We can observe this problem, when
unregister_virtio_device() does not give up the last reference to the
virtio_device (e.g. because a virtio-scsi attached scsi disk got removed
without previously unmounting its previously mounted partition).
To make sure that the genpool is only destroyed after all the necessary
freeing is done let us take a reference on the ccw device on each
ccw_device_dma_zalloc() and give it up on each ccw_device_dma_free().
Actually there are multiple approaches to fixing the problem at hand
that can work. The upside of this one is that it is the safest one while
remaining simple. We don't crash the guest even if the driver does not
pair allocations and frees. The downside is the reference counting
overhead, that the reference counting for ccw devices becomes more
complex, in a sense that we need to pair the calls to the aforementioned
functions for it to be correct, and that if we happen to leak, we leak
more than necessary (the whole ccw device instead of just the genpool).
Some alternatives to this approach are taking a reference in
virtio_ccw_online() and giving it up in virtio_ccw_release_dev() or
making sure virtio_ccw_release_dev() completes its work before
virtio_ccw_remove() returns. The downside of these approaches is that
these are less safe against programming errors.
Cc: <stable(a)vger.kernel.org> # v5.3
Signed-off-by: Halil Pasic <pasic(a)linux.ibm.com>
Fixes: 48720ba56891 ("virtio/s390: use DMA memory for ccw I/O and
classic notifiers")
Reported-by: bfu(a)redhat.com
---
FYI I've proposed a different fix to this very same problem:
https://lore.kernel.org/lkml/20210915215742.1793314-1-pasic@linux.ibm.com/
This patch is more or less a result of that discussion.
---
drivers/s390/cio/device_ops.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index 0fe7b2f2e7f5..c533d1dadc6b 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -825,13 +825,23 @@ EXPORT_SYMBOL_GPL(ccw_device_get_chid);
*/
void *ccw_device_dma_zalloc(struct ccw_device *cdev, size_t size)
{
- return cio_gp_dma_zalloc(cdev->private->dma_pool, &cdev->dev, size);
+ void *addr;
+
+ if (!get_device(&cdev->dev))
+ return NULL;
+ addr = cio_gp_dma_zalloc(cdev->private->dma_pool, &cdev->dev, size);
+ if (IS_ERR_OR_NULL(addr))
+ put_device(&cdev->dev);
+ return addr;
}
EXPORT_SYMBOL(ccw_device_dma_zalloc);
void ccw_device_dma_free(struct ccw_device *cdev, void *cpu_addr, size_t size)
{
+ if (!cpu_addr)
+ return;
cio_gp_dma_free(cdev->private->dma_pool, cpu_addr, size);
+ put_device(&cdev->dev);
}
EXPORT_SYMBOL(ccw_device_dma_free);
base-commit: 64570fbc14f8d7cb3fe3995f20e26bc25ce4b2cc
--
2.25.1
> By working with external hardware ECC engines, we figured out that
> Under certain circumstances, it is needed for the SPI controller to
> check INT_TX_EMPTY and INT_RX_NOT_EMPTY in both receive and transmit
> path (not only in the receive path). The delay penalty being
> negligible, move this code in the common path.
>
> Fixes: b942d80b0a39 ("spi: Add MXIC controller driver")
> Cc: stable(a)vger.kernel.org
> Suggested-by: Mason Yang <masonccyang(a)mxic.com.tw>
> Signed-off-by: Miquel Raynal <miquel.raynal(a)bootlin.com>
> ---
> drivers/spi/spi-mxic.c | 28 ++++++++++++----------------
> 1 file changed, 12 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c
> index 96b418293bf2..4fb19e6f94b0 100644
> --- a/drivers/spi/spi-mxic.c
> +++ b/drivers/spi/spi-mxic.c
> @@ -304,25 +304,21 @@ static int mxic_spi_data_xfer(struct mxic_spi
> *mxic, const void *txbuf,
>
> writel(data, mxic->regs + TXD(nbytes % 4));
>
> + ret = readl_poll_timeout(mxic->regs + INT_STS, sts,
> + sts & INT_TX_EMPTY, 0, USEC_PER_SEC);
> + if (ret)
> + return ret;
> +
> + ret = readl_poll_timeout(mxic->regs + INT_STS, sts,
> + sts & INT_RX_NOT_EMPTY, 0,
> + USEC_PER_SEC);
> + if (ret)
> + return ret;
> +
> + data = readl(mxic->regs + RXD);
> if (rxbuf) {
> - ret = readl_poll_timeout(mxic->regs + INT_STS, sts,
> - sts & INT_TX_EMPTY, 0,
> - USEC_PER_SEC);
> - if (ret)
> - return ret;
> -
> - ret = readl_poll_timeout(mxic->regs + INT_STS, sts,
> - sts & INT_RX_NOT_EMPTY, 0,
> - USEC_PER_SEC);
> - if (ret)
> - return ret;
> -
> - data = readl(mxic->regs + RXD);
> data >>= (8 * (4 - nbytes));
> memcpy(rxbuf + pos, &data, nbytes);
> - WARN_ON(readl(mxic->regs + INT_STS) & INT_RX_NOT_EMPTY);
> - } else {
> - readl(mxic->regs + RXD);
> }
> WARN_ON(readl(mxic->regs + INT_STS) & INT_RX_NOT_EMPTY);
>
> --
> 2.27.0
>
Reviewed-by: Zhengxun Li <zhengxunli(a)mxic.com.tw>
CONFIDENTIALITY NOTE:
This e-mail and any attachments may contain confidential information
and/or personal data, which is protected by applicable laws. Please be
reminded that duplication, disclosure, distribution, or use of this e-mail
(and/or its attachments) or any part thereof is prohibited. If you receive
this e-mail in error, please notify us immediately and delete this mail as
well as its attachment(s) from your system. In addition, please be
informed that collection, processing, and/or use of personal data is
prohibited unless expressly permitted by personal data protection laws.
Thank you for your attention and cooperation.
Macronix International Co., Ltd.
=====================================================================
============================================================================
CONFIDENTIALITY NOTE:
This e-mail and any attachments may contain confidential information and/or personal data, which is protected by applicable laws. Please be reminded that duplication, disclosure, distribution, or use of this e-mail (and/or its attachments) or any part thereof is prohibited. If you receive this e-mail in error, please notify us immediately and delete this mail as well as its attachment(s) from your system. In addition, please be informed that collection, processing, and/or use of personal data is prohibited unless expressly permitted by personal data protection laws. Thank you for your attention and cooperation.
Macronix International Co., Ltd.
=====================================================================