5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael S. Tsirkin mst@redhat.com
[ Upstream commit b9efbe2b8f0177fa97bfab290d60858900aa196b ]
This fixes the following issue discovered by code review:
after vqs have been created, a buggy device can send an interrupt.
A control vq callback will then try to schedule control_work which has not been initialized yet. Similarly for config interrupt. Further, in and out vq callbacks invoke find_port_by_vq which attempts to take ports_lock which also has not been initialized.
To fix, init all locks and work before creating vqs.
Message-ID: ad982e975a6160ad110c623c016041311ca15b4f.1726511547.git.mst@redhat.com Fixes: 17634ba25544 ("virtio: console: Add a new MULTIPORT feature, support for generic ports") Signed-off-by: Michael S. Tsirkin mst@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/char/virtio_console.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 77bc993d75130..a5d38fdc25897 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -2046,25 +2046,27 @@ static int virtcons_probe(struct virtio_device *vdev) multiport = true; }
- err = init_vqs(portdev); - if (err < 0) { - dev_err(&vdev->dev, "Error %d initializing vqs\n", err); - goto free_chrdev; - } - spin_lock_init(&portdev->ports_lock); INIT_LIST_HEAD(&portdev->ports); INIT_LIST_HEAD(&portdev->list);
- virtio_device_ready(portdev->vdev); - INIT_WORK(&portdev->config_work, &config_work_handler); INIT_WORK(&portdev->control_work, &control_work_handler);
if (multiport) { spin_lock_init(&portdev->c_ivq_lock); spin_lock_init(&portdev->c_ovq_lock); + }
+ err = init_vqs(portdev); + if (err < 0) { + dev_err(&vdev->dev, "Error %d initializing vqs\n", err); + goto free_chrdev; + } + + virtio_device_ready(portdev->vdev); + + if (multiport) { err = fill_queue(portdev->c_ivq, &portdev->c_ivq_lock); if (err < 0) { dev_err(&vdev->dev,