aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/virtio_console.c
diff options
context:
space:
mode:
authorAmit Shah <amit.shah@redhat.com>2009-11-26 00:55:38 -0500
committerRusty Russell <rusty@rustcorp.com.au>2010-02-23 22:52:55 -0500
commit3c7969ccb569968a79fab3729075751bc8fc2f78 (patch)
treec5f9d8362d8b448961cb0bf355a445e14646dec4 /drivers/char/virtio_console.c
parent2030fa496d74b49220308eaccf656e2338019cfd (diff)
virtio: console: Ensure only one process can have a port open at a time
Add a guest_connected field that ensures only one process can have a port open at a time. This also ensures we don't have a race when we later add support for dropping buffers when closing the char dev and buffer caching is turned off for the particular port. Signed-off-by: Amit Shah <amit.shah@redhat.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers/char/virtio_console.c')
-rw-r--r--drivers/char/virtio_console.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index ece1546fbb20..5e3503a31312 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -175,6 +175,9 @@ struct port {
175 175
176 /* Is the host device open */ 176 /* Is the host device open */
177 bool host_connected; 177 bool host_connected;
178
179 /* We should allow only one process to open a port */
180 bool guest_connected;
178}; 181};
179 182
180/* This is the very early arch-specified put chars function. */ 183/* This is the very early arch-specified put chars function. */
@@ -528,6 +531,8 @@ static int port_fops_release(struct inode *inode, struct file *filp)
528 /* Notify host of port being closed */ 531 /* Notify host of port being closed */
529 send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 0); 532 send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 0);
530 533
534 port->guest_connected = false;
535
531 return 0; 536 return 0;
532} 537}
533 538
@@ -546,6 +551,16 @@ static int port_fops_open(struct inode *inode, struct file *filp)
546 if (is_console_port(port)) 551 if (is_console_port(port))
547 return -ENXIO; 552 return -ENXIO;
548 553
554 /* Allow only one process to open a particular port at a time */
555 spin_lock_irq(&port->inbuf_lock);
556 if (port->guest_connected) {
557 spin_unlock_irq(&port->inbuf_lock);
558 return -EMFILE;
559 }
560
561 port->guest_connected = true;
562 spin_unlock_irq(&port->inbuf_lock);
563
549 /* Notify host of port being opened */ 564 /* Notify host of port being opened */
550 send_control_msg(filp->private_data, VIRTIO_CONSOLE_PORT_OPEN, 1); 565 send_control_msg(filp->private_data, VIRTIO_CONSOLE_PORT_OPEN, 1);
551 566
@@ -709,6 +724,7 @@ int init_port_console(struct port *port)
709 pdrvdata.next_vtermno++; 724 pdrvdata.next_vtermno++;
710 list_add_tail(&port->cons.list, &pdrvdata.consoles); 725 list_add_tail(&port->cons.list, &pdrvdata.consoles);
711 spin_unlock_irq(&pdrvdata_lock); 726 spin_unlock_irq(&pdrvdata_lock);
727 port->guest_connected = true;
712 728
713 /* Notify host of port being opened */ 729 /* Notify host of port being opened */
714 send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 1); 730 send_control_msg(port, VIRTIO_CONSOLE_PORT_OPEN, 1);
@@ -856,7 +872,7 @@ static int add_port(struct ports_device *portdev, u32 id)
856 port->inbuf = NULL; 872 port->inbuf = NULL;
857 port->cons.hvc = NULL; 873 port->cons.hvc = NULL;
858 874
859 port->host_connected = false; 875 port->host_connected = port->guest_connected = false;
860 876
861 port->in_vq = portdev->in_vqs[port->id]; 877 port->in_vq = portdev->in_vqs[port->id];
862 port->out_vq = portdev->out_vqs[port->id]; 878 port->out_vq = portdev->out_vqs[port->id];