aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/virtio_console.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 387fcdf019b7..4ca181f1378b 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -19,6 +19,7 @@
19 */ 19 */
20#include <linux/cdev.h> 20#include <linux/cdev.h>
21#include <linux/debugfs.h> 21#include <linux/debugfs.h>
22#include <linux/completion.h>
22#include <linux/device.h> 23#include <linux/device.h>
23#include <linux/err.h> 24#include <linux/err.h>
24#include <linux/freezer.h> 25#include <linux/freezer.h>
@@ -74,6 +75,7 @@ struct ports_driver_data {
74static struct ports_driver_data pdrvdata; 75static struct ports_driver_data pdrvdata;
75 76
76DEFINE_SPINLOCK(pdrvdata_lock); 77DEFINE_SPINLOCK(pdrvdata_lock);
78DECLARE_COMPLETION(early_console_added);
77 79
78/* This struct holds information that's relevant only for console ports */ 80/* This struct holds information that's relevant only for console ports */
79struct console { 81struct console {
@@ -1366,6 +1368,7 @@ static void handle_control_message(struct ports_device *portdev,
1366 break; 1368 break;
1367 1369
1368 init_port_console(port); 1370 init_port_console(port);
1371 complete(&early_console_added);
1369 /* 1372 /*
1370 * Could remove the port here in case init fails - but 1373 * Could remove the port here in case init fails - but
1371 * have to notify the host first. 1374 * have to notify the host first.
@@ -1668,6 +1671,10 @@ static int __devinit virtcons_probe(struct virtio_device *vdev)
1668 struct ports_device *portdev; 1671 struct ports_device *portdev;
1669 int err; 1672 int err;
1670 bool multiport; 1673 bool multiport;
1674 bool early = early_put_chars != NULL;
1675
1676 /* Ensure to read early_put_chars now */
1677 barrier();
1671 1678
1672 portdev = kmalloc(sizeof(*portdev), GFP_KERNEL); 1679 portdev = kmalloc(sizeof(*portdev), GFP_KERNEL);
1673 if (!portdev) { 1680 if (!portdev) {
@@ -1737,6 +1744,19 @@ static int __devinit virtcons_probe(struct virtio_device *vdev)
1737 1744
1738 __send_control_msg(portdev, VIRTIO_CONSOLE_BAD_ID, 1745 __send_control_msg(portdev, VIRTIO_CONSOLE_BAD_ID,
1739 VIRTIO_CONSOLE_DEVICE_READY, 1); 1746 VIRTIO_CONSOLE_DEVICE_READY, 1);
1747
1748 /*
1749 * If there was an early virtio console, assume that there are no
1750 * other consoles. We need to wait until the hvc_alloc matches the
1751 * hvc_instantiate, otherwise tty_open will complain, resulting in
1752 * a "Warning: unable to open an initial console" boot failure.
1753 * Without multiport this is done in add_port above. With multiport
1754 * this might take some host<->guest communication - thus we have to
1755 * wait.
1756 */
1757 if (multiport && early)
1758 wait_for_completion(&early_console_added);
1759
1740 return 0; 1760 return 0;
1741 1761
1742free_vqs: 1762free_vqs: