Patchwork [3.5.y.z,extended,stable] Patch "virtio: console: add locking around c_ovq operations" has been added to staging queue

mail settings
Submitter Luis Henriques
Date April 4, 2013, 1:26 p.m.
Message ID <>
Download mbox | patch
Permalink /patch/233815/
State New
Headers show


Luis Henriques - April 4, 2013, 1:26 p.m.
This is a note to let you know that I have just added a patch titled

    virtio: console: add locking around c_ovq operations

to the linux-3.5.y-queue branch of the 3.5.y.z extended stable tree 
which can be found at:;a=shortlog;h=refs/heads/linux-3.5.y-queue

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.5.y.z tree, see



From 60e6ac0f5c8f24b40a7f9f348804279df5641883 Mon Sep 17 00:00:00 2001
From: Amit Shah <>
Date: Fri, 29 Mar 2013 16:30:08 +0530
Subject: [PATCH] virtio: console: add locking around c_ovq operations

commit 9ba5c80b1aea8648a3efe5f22dc1f7cacdfbeeb8 upstream.

When multiple ovq operations are being performed (lots of open/close
operations on virtio_console fds), the __send_control_msg() function can
get confused without locking.

A simple recipe to cause badness is:
* create a QEMU VM with two virtio-serial ports
* in the guest, do
  while true;do echo abc >/dev/vport0p1;done
  while true;do echo edf >/dev/vport0p2;done

In one run, this caused a panic in __send_control_msg().  In another, I

   virtio_console virtio0: control-o:id 0 is not a head!

This also results repeated messages similar to these on the host:

  qemu-kvm: virtio-serial-bus: Unexpected port id 478762112 for device virtio-serial-bus.0
  qemu-kvm: virtio-serial-bus: Unexpected port id 478762368 for device virtio-serial-bus.0

Reported-by: FuXiangChun <>
Signed-off-by: Amit Shah <>
Reviewed-by: Wanlong Gao <>
Reviewed-by: Asias He <>
Signed-off-by: Rusty Russell <>
[ luis: adjust context ]
Signed-off-by: Luis Henriques <>
 drivers/char/virtio_console.c | 4 ++++
 1 file changed, 4 insertions(+)



diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 4c76834..957f293 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -132,6 +132,7 @@  struct ports_device {

 	/* To protect the vq operations for the control channel */
 	spinlock_t c_ivq_lock;
+	spinlock_t c_ovq_lock;

 	/* The current config space is stored here */
 	struct virtio_console_config config;
@@ -457,11 +458,13 @@  static ssize_t __send_control_msg(struct ports_device *portdev, u32 port_id,
 	vq = portdev->c_ovq;

 	sg_init_one(sg, &cpkt, sizeof(cpkt));
+	spin_lock(&portdev->c_ovq_lock);
 	if (virtqueue_add_buf(vq, sg, 1, 0, &cpkt, GFP_ATOMIC) >= 0) {
 		while (!virtqueue_get_buf(vq, &len))
+	spin_unlock(&portdev->c_ovq_lock);
 	return 0;

@@ -1743,6 +1746,7 @@  static int __devinit virtcons_probe(struct virtio_device *vdev)
 		unsigned int nr_added_bufs;

+		spin_lock_init(&portdev->c_ovq_lock);
 		INIT_WORK(&portdev->control_work, &control_work_handler);

 		nr_added_bufs = fill_queue(portdev->c_ivq,