media-b2c2-flexcop-usb-add-sanity-checking.patch
media-cxusb-detect-cxusb_ctrl_msg-error-in-query.patch
media-imon-invalid-dereference-in-imon_touch_event.patch
+virtio_console-reset-on-out-of-memory.patch
+virtio_console-don-t-tie-bufs-to-a-vq.patch
+virtio_console-allocate-inbufs-in-add_port-only-if-i.patch
+virtio_ring-fix-return-code-on-dma-mapping-fails.patch
+virtio_console-fix-uninitialized-variable-use.patch
+virtio_console-drop-custom-control-queue-cleanup.patch
+virtio_console-move-removal-code.patch
--- /dev/null
+From b2a3754130c80ae9cfd62de52f4a95789c85226b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Nov 2019 13:25:48 +0100
+Subject: virtio_console: allocate inbufs in add_port() only if it is needed
+
+From: Laurent Vivier <lvivier@redhat.com>
+
+[ Upstream commit d791cfcbf98191122af70b053a21075cb450d119 ]
+
+When we hot unplug a virtserialport and then try to hot plug again,
+it fails:
+
+(qemu) chardev-add socket,id=serial0,path=/tmp/serial0,server,nowait
+(qemu) device_add virtserialport,bus=virtio-serial0.0,nr=2,\
+ chardev=serial0,id=serial0,name=serial0
+(qemu) device_del serial0
+(qemu) device_add virtserialport,bus=virtio-serial0.0,nr=2,\
+ chardev=serial0,id=serial0,name=serial0
+kernel error:
+ virtio-ports vport2p2: Error allocating inbufs
+qemu error:
+ virtio-serial-bus: Guest failure in adding port 2 for device \
+ virtio-serial0.0
+
+This happens because buffers for the in_vq are allocated when the port is
+added but are not released when the port is unplugged.
+
+They are only released when virtconsole is removed (see a7a69ec0d8e4)
+
+To avoid the problem and to be symmetric, we could allocate all the buffers
+in init_vqs() as they are released in remove_vqs(), but it sounds like
+a waste of memory.
+
+Rather than that, this patch changes add_port() logic to ignore ENOSPC
+error in fill_queue(), which means queue has already been filled.
+
+Fixes: a7a69ec0d8e4 ("virtio_console: free buffers after reset")
+Cc: mst@redhat.com
+Cc: stable@vger.kernel.org
+Signed-off-by: Laurent Vivier <lvivier@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/virtio_console.c | 28 +++++++++++++---------------
+ 1 file changed, 13 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
+index b09fc4553dc81..d7ee031d776d8 100644
+--- a/drivers/char/virtio_console.c
++++ b/drivers/char/virtio_console.c
+@@ -1369,24 +1369,24 @@ static void set_console_size(struct port *port, u16 rows, u16 cols)
+ port->cons.ws.ws_col = cols;
+ }
+
+-static unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock)
++static int fill_queue(struct virtqueue *vq, spinlock_t *lock)
+ {
+ struct port_buffer *buf;
+- unsigned int nr_added_bufs;
++ int nr_added_bufs;
+ int ret;
+
+ nr_added_bufs = 0;
+ do {
+ buf = alloc_buf(vq->vdev, PAGE_SIZE, 0);
+ if (!buf)
+- break;
++ return -ENOMEM;
+
+ spin_lock_irq(lock);
+ ret = add_inbuf(vq, buf);
+ if (ret < 0) {
+ spin_unlock_irq(lock);
+ free_buf(buf, true);
+- break;
++ return ret;
+ }
+ nr_added_bufs++;
+ spin_unlock_irq(lock);
+@@ -1406,7 +1406,6 @@ static int add_port(struct ports_device *portdev, u32 id)
+ char debugfs_name[16];
+ struct port *port;
+ dev_t devt;
+- unsigned int nr_added_bufs;
+ int err;
+
+ port = kmalloc(sizeof(*port), GFP_KERNEL);
+@@ -1465,11 +1464,13 @@ static int add_port(struct ports_device *portdev, u32 id)
+ spin_lock_init(&port->outvq_lock);
+ init_waitqueue_head(&port->waitqueue);
+
+- /* Fill the in_vq with buffers so the host can send us data. */
+- nr_added_bufs = fill_queue(port->in_vq, &port->inbuf_lock);
+- if (!nr_added_bufs) {
++ /* We can safely ignore ENOSPC because it means
++ * the queue already has buffers. Buffers are removed
++ * only by virtcons_remove(), not by unplug_port()
++ */
++ err = fill_queue(port->in_vq, &port->inbuf_lock);
++ if (err < 0 && err != -ENOSPC) {
+ dev_err(port->dev, "Error allocating inbufs\n");
+- err = -ENOMEM;
+ goto free_device;
+ }
+
+@@ -2081,14 +2082,11 @@ static int virtcons_probe(struct virtio_device *vdev)
+ INIT_WORK(&portdev->control_work, &control_work_handler);
+
+ if (multiport) {
+- unsigned int nr_added_bufs;
+-
+ spin_lock_init(&portdev->c_ivq_lock);
+ spin_lock_init(&portdev->c_ovq_lock);
+
+- nr_added_bufs = fill_queue(portdev->c_ivq,
+- &portdev->c_ivq_lock);
+- if (!nr_added_bufs) {
++ err = fill_queue(portdev->c_ivq, &portdev->c_ivq_lock);
++ if (err < 0) {
+ dev_err(&vdev->dev,
+ "Error allocating buffers for control queue\n");
+ /*
+@@ -2099,7 +2097,7 @@ static int virtcons_probe(struct virtio_device *vdev)
+ VIRTIO_CONSOLE_DEVICE_READY, 0);
+ /* Device was functional: we need full cleanup. */
+ virtcons_remove(vdev);
+- return -ENOMEM;
++ return err;
+ }
+ } else {
+ /*
+--
+2.20.1
+
--- /dev/null
+From d70fa69e576d57ed72fe5f8ac02d521c9eea2fb9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Apr 2018 19:54:23 +0300
+Subject: virtio_console: don't tie bufs to a vq
+
+From: Michael S. Tsirkin <mst@redhat.com>
+
+[ Upstream commit 2855b33514d290c51d52d94e25d3ef942cd4d578 ]
+
+an allocated buffer doesn't need to be tied to a vq -
+only vq->vdev is ever used. Pass the function the
+just what it needs - the vdev.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/virtio_console.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
+index 43724bd8a0c0a..b09fc4553dc81 100644
+--- a/drivers/char/virtio_console.c
++++ b/drivers/char/virtio_console.c
+@@ -422,7 +422,7 @@ static void reclaim_dma_bufs(void)
+ }
+ }
+
+-static struct port_buffer *alloc_buf(struct virtqueue *vq, size_t buf_size,
++static struct port_buffer *alloc_buf(struct virtio_device *vdev, size_t buf_size,
+ int pages)
+ {
+ struct port_buffer *buf;
+@@ -445,7 +445,7 @@ static struct port_buffer *alloc_buf(struct virtqueue *vq, size_t buf_size,
+ return buf;
+ }
+
+- if (is_rproc_serial(vq->vdev)) {
++ if (is_rproc_serial(vdev)) {
+ /*
+ * Allocate DMA memory from ancestor. When a virtio
+ * device is created by remoteproc, the DMA memory is
+@@ -455,9 +455,9 @@ static struct port_buffer *alloc_buf(struct virtqueue *vq, size_t buf_size,
+ * DMA_MEMORY_INCLUDES_CHILDREN had been supported
+ * in dma-coherent.c
+ */
+- if (!vq->vdev->dev.parent || !vq->vdev->dev.parent->parent)
++ if (!vdev->dev.parent || !vdev->dev.parent->parent)
+ goto free_buf;
+- buf->dev = vq->vdev->dev.parent->parent;
++ buf->dev = vdev->dev.parent->parent;
+
+ /* Increase device refcnt to avoid freeing it */
+ get_device(buf->dev);
+@@ -841,7 +841,7 @@ static ssize_t port_fops_write(struct file *filp, const char __user *ubuf,
+
+ count = min((size_t)(32 * 1024), count);
+
+- buf = alloc_buf(port->out_vq, count, 0);
++ buf = alloc_buf(port->portdev->vdev, count, 0);
+ if (!buf)
+ return -ENOMEM;
+
+@@ -960,7 +960,7 @@ static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe,
+ if (ret < 0)
+ goto error_out;
+
+- buf = alloc_buf(port->out_vq, 0, pipe->nrbufs);
++ buf = alloc_buf(port->portdev->vdev, 0, pipe->nrbufs);
+ if (!buf) {
+ ret = -ENOMEM;
+ goto error_out;
+@@ -1377,7 +1377,7 @@ static unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock)
+
+ nr_added_bufs = 0;
+ do {
+- buf = alloc_buf(vq, PAGE_SIZE, 0);
++ buf = alloc_buf(vq->vdev, PAGE_SIZE, 0);
+ if (!buf)
+ break;
+
+--
+2.20.1
+
--- /dev/null
+From 0b56b71d274a803d1e71c64f8d332835b9d8417c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Apr 2018 20:49:04 +0300
+Subject: virtio_console: drop custom control queue cleanup
+
+From: Michael S. Tsirkin <mst@redhat.com>
+
+[ Upstream commit 61a8950c5c5708cf2068b29ffde94e454e528208 ]
+
+We now cleanup all VQs on device removal - no need
+to handle the control VQ specially.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/virtio_console.c | 17 -----------------
+ 1 file changed, 17 deletions(-)
+
+diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
+index 7de24040f39c1..8975ea08d6c01 100644
+--- a/drivers/char/virtio_console.c
++++ b/drivers/char/virtio_console.c
+@@ -1993,21 +1993,6 @@ static void remove_vqs(struct ports_device *portdev)
+ kfree(portdev->out_vqs);
+ }
+
+-static void remove_controlq_data(struct ports_device *portdev)
+-{
+- struct port_buffer *buf;
+- unsigned int len;
+-
+- if (!use_multiport(portdev))
+- return;
+-
+- while ((buf = virtqueue_get_buf(portdev->c_ivq, &len)))
+- free_buf(buf, true);
+-
+- while ((buf = virtqueue_detach_unused_buf(portdev->c_ivq)))
+- free_buf(buf, true);
+-}
+-
+ /*
+ * Once we're further in boot, we get probed like any other virtio
+ * device.
+@@ -2168,7 +2153,6 @@ static void virtcons_remove(struct virtio_device *vdev)
+ * have to just stop using the port, as the vqs are going
+ * away.
+ */
+- remove_controlq_data(portdev);
+ remove_vqs(portdev);
+ kfree(portdev);
+ }
+@@ -2213,7 +2197,6 @@ static int virtcons_freeze(struct virtio_device *vdev)
+ */
+ if (use_multiport(portdev))
+ virtqueue_disable_cb(portdev->c_ivq);
+- remove_controlq_data(portdev);
+
+ list_for_each_entry(port, &portdev->ports, list) {
+ virtqueue_disable_cb(port->in_vq);
+--
+2.20.1
+
--- /dev/null
+From 09e842f520117a693714a7d3eac8becc1ff77cdf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Mar 2017 23:22:04 +0300
+Subject: virtio_console: fix uninitialized variable use
+
+From: Michael S. Tsirkin <mst@redhat.com>
+
+[ Upstream commit 2055997f983c6db7b5c3940ce5f8f822657d5bc3 ]
+
+We try to disable callbacks on c_ivq even without multiport
+even though that vq is not initialized in this configuration.
+
+Fixes: c743d09dbd01 ("virtio: console: Disable callbacks for virtqueues at start of S4 freeze")
+Suggested-by: Mike Galbraith <efault@gmx.de>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/virtio_console.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
+index d7ee031d776d8..7de24040f39c1 100644
+--- a/drivers/char/virtio_console.c
++++ b/drivers/char/virtio_console.c
+@@ -2203,14 +2203,16 @@ static int virtcons_freeze(struct virtio_device *vdev)
+
+ vdev->config->reset(vdev);
+
+- virtqueue_disable_cb(portdev->c_ivq);
++ if (use_multiport(portdev))
++ virtqueue_disable_cb(portdev->c_ivq);
+ cancel_work_sync(&portdev->control_work);
+ cancel_work_sync(&portdev->config_work);
+ /*
+ * Once more: if control_work_handler() was running, it would
+ * enable the cb as the last step.
+ */
+- virtqueue_disable_cb(portdev->c_ivq);
++ if (use_multiport(portdev))
++ virtqueue_disable_cb(portdev->c_ivq);
+ remove_controlq_data(portdev);
+
+ list_for_each_entry(port, &portdev->ports, list) {
+--
+2.20.1
+
--- /dev/null
+From 7ea4ae4a552dfdc0bef56ecdba7af2a0f1194546 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Apr 2018 20:51:18 +0300
+Subject: virtio_console: move removal code
+
+From: Michael S. Tsirkin <mst@redhat.com>
+
+[ Upstream commit aa44ec867030a72e8aa127977e37dec551d8df19 ]
+
+Will make it reusable for error handling.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/virtio_console.c | 72 +++++++++++++++++------------------
+ 1 file changed, 36 insertions(+), 36 deletions(-)
+
+diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
+index 8975ea08d6c01..34548d3b4d13c 100644
+--- a/drivers/char/virtio_console.c
++++ b/drivers/char/virtio_console.c
+@@ -1993,6 +1993,42 @@ static void remove_vqs(struct ports_device *portdev)
+ kfree(portdev->out_vqs);
+ }
+
++static void virtcons_remove(struct virtio_device *vdev)
++{
++ struct ports_device *portdev;
++ struct port *port, *port2;
++
++ portdev = vdev->priv;
++
++ spin_lock_irq(&pdrvdata_lock);
++ list_del(&portdev->list);
++ spin_unlock_irq(&pdrvdata_lock);
++
++ /* Disable interrupts for vqs */
++ vdev->config->reset(vdev);
++ /* Finish up work that's lined up */
++ if (use_multiport(portdev))
++ cancel_work_sync(&portdev->control_work);
++ else
++ cancel_work_sync(&portdev->config_work);
++
++ list_for_each_entry_safe(port, port2, &portdev->ports, list)
++ unplug_port(port);
++
++ unregister_chrdev(portdev->chr_major, "virtio-portsdev");
++
++ /*
++ * When yanking out a device, we immediately lose the
++ * (device-side) queues. So there's no point in keeping the
++ * guest side around till we drop our final reference. This
++ * also means that any ports which are in an open state will
++ * have to just stop using the port, as the vqs are going
++ * away.
++ */
++ remove_vqs(portdev);
++ kfree(portdev);
++}
++
+ /*
+ * Once we're further in boot, we get probed like any other virtio
+ * device.
+@@ -2121,42 +2157,6 @@ fail:
+ return err;
+ }
+
+-static void virtcons_remove(struct virtio_device *vdev)
+-{
+- struct ports_device *portdev;
+- struct port *port, *port2;
+-
+- portdev = vdev->priv;
+-
+- spin_lock_irq(&pdrvdata_lock);
+- list_del(&portdev->list);
+- spin_unlock_irq(&pdrvdata_lock);
+-
+- /* Disable interrupts for vqs */
+- vdev->config->reset(vdev);
+- /* Finish up work that's lined up */
+- if (use_multiport(portdev))
+- cancel_work_sync(&portdev->control_work);
+- else
+- cancel_work_sync(&portdev->config_work);
+-
+- list_for_each_entry_safe(port, port2, &portdev->ports, list)
+- unplug_port(port);
+-
+- unregister_chrdev(portdev->chr_major, "virtio-portsdev");
+-
+- /*
+- * When yanking out a device, we immediately lose the
+- * (device-side) queues. So there's no point in keeping the
+- * guest side around till we drop our final reference. This
+- * also means that any ports which are in an open state will
+- * have to just stop using the port, as the vqs are going
+- * away.
+- */
+- remove_vqs(portdev);
+- kfree(portdev);
+-}
+-
+ static struct virtio_device_id id_table[] = {
+ { VIRTIO_ID_CONSOLE, VIRTIO_DEV_ANY_ID },
+ { 0 },
+--
+2.20.1
+
--- /dev/null
+From 24f3db13ca87f53ca4c5fca4b50d49fb2b0f9c8d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Apr 2018 21:00:13 +0300
+Subject: virtio_console: reset on out of memory
+
+From: Michael S. Tsirkin <mst@redhat.com>
+
+[ Upstream commit 5c60300d68da32ca77f7f978039dc72bfc78b06b ]
+
+When out of memory and we can't add ctrl vq buffers,
+probe fails. Unfortunately the error handling is
+out of spec: it calls del_vqs without bothering
+to reset the device first.
+
+To fix, call the full cleanup function in this case.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/char/virtio_console.c | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
+index 800ced0a5a247..43724bd8a0c0a 100644
+--- a/drivers/char/virtio_console.c
++++ b/drivers/char/virtio_console.c
+@@ -2073,6 +2073,7 @@ static int virtcons_probe(struct virtio_device *vdev)
+
+ spin_lock_init(&portdev->ports_lock);
+ INIT_LIST_HEAD(&portdev->ports);
++ INIT_LIST_HEAD(&portdev->list);
+
+ virtio_device_ready(portdev->vdev);
+
+@@ -2090,8 +2091,15 @@ static int virtcons_probe(struct virtio_device *vdev)
+ if (!nr_added_bufs) {
+ dev_err(&vdev->dev,
+ "Error allocating buffers for control queue\n");
+- err = -ENOMEM;
+- goto free_vqs;
++ /*
++ * The host might want to notify mgmt sw about device
++ * add failure.
++ */
++ __send_control_msg(portdev, VIRTIO_CONSOLE_BAD_ID,
++ VIRTIO_CONSOLE_DEVICE_READY, 0);
++ /* Device was functional: we need full cleanup. */
++ virtcons_remove(vdev);
++ return -ENOMEM;
+ }
+ } else {
+ /*
+@@ -2122,11 +2130,6 @@ static int virtcons_probe(struct virtio_device *vdev)
+
+ return 0;
+
+-free_vqs:
+- /* The host might want to notify mgmt sw about device add failure */
+- __send_control_msg(portdev, VIRTIO_CONSOLE_BAD_ID,
+- VIRTIO_CONSOLE_DEVICE_READY, 0);
+- remove_vqs(portdev);
+ free_chrdev:
+ unregister_chrdev(portdev->chr_major, "virtio-portsdev");
+ free:
+--
+2.20.1
+
--- /dev/null
+From b905cff5988a7998d7e3b14ddaf776d5dff3577a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Nov 2019 13:46:46 +0100
+Subject: virtio_ring: fix return code on DMA mapping fails
+
+From: Halil Pasic <pasic@linux.ibm.com>
+
+[ Upstream commit f7728002c1c7bfa787b276a31c3ef458739b8e7c ]
+
+Commit 780bc7903a32 ("virtio_ring: Support DMA APIs") makes
+virtqueue_add() return -EIO when we fail to map our I/O buffers. This is
+a very realistic scenario for guests with encrypted memory, as swiotlb
+may run out of space, depending on it's size and the I/O load.
+
+The virtio-blk driver interprets -EIO form virtqueue_add() as an IO
+error, despite the fact that swiotlb full is in absence of bugs a
+recoverable condition.
+
+Let us change the return code to -ENOMEM, and make the block layer
+recover form these failures when virtio-blk encounters the condition
+described above.
+
+Cc: stable@vger.kernel.org
+Fixes: 780bc7903a32 ("virtio_ring: Support DMA APIs")
+Signed-off-by: Halil Pasic <pasic@linux.ibm.com>
+Tested-by: Michael Mueller <mimu@linux.ibm.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/virtio/virtio_ring.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
+index 2f09294c59460..e459cd7302e27 100644
+--- a/drivers/virtio/virtio_ring.c
++++ b/drivers/virtio/virtio_ring.c
+@@ -427,7 +427,7 @@ unmap_release:
+ kfree(desc);
+
+ END_USE(vq);
+- return -EIO;
++ return -ENOMEM;
+ }
+
+ /**
+--
+2.20.1
+