cons: Fix initialization bug
authorBarret Rhoden <brho@cs.berkeley.edu>
Tue, 24 Jan 2017 16:48:30 +0000 (11:48 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 9 Feb 2017 17:31:08 +0000 (12:31 -0500)
We could receive an IRQ early during boot: after arch_init(), but before
cons_init().  That would attempt to write to an uninitialized queue.  This
would happen periodically in QEMU, and maybe it was more likely when I was
hitting keys during boot.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/drivers/dev/cons.c

index ec4069e..572caf5 100644 (file)
@@ -35,6 +35,7 @@ atomic_t kprintinuse = 0;             /* test and set whether /dev/kprint is open */
 int iprintscreenputs = 1;
 int keepbroken = 1;
 
+static bool cons_has_init = FALSE;
 struct queue *cons_q;                  /* Akaros cons input: keyboard, serial, etc */
 spinlock_t cons_q_lock = SPINLOCK_INITIALIZER;
 struct fdtap_slist cons_q_fd_taps = SLIST_HEAD_INITIALIZER(cons_q_fd_taps);
@@ -698,6 +699,8 @@ static void consinit(void)
 #if 0
        addclock0link(kbdputcclock, 22);
 #endif
+       cmb();  /* single-core, just need previous instructions to be issued. */
+       cons_has_init = TRUE;
 }
 
 static char *devname(void);
@@ -1650,7 +1653,13 @@ void killkid(void)
        proc_decref(victim);
 }
 
+/* This can be called any time after arch_init()->cons_irq_init().  That can
+ * happen *before* the console device is initialized (devtab{reset,init}()).
+ *
+ * All other functions in #cons shouldn't be called until after cons_init(). */
 void cons_add_char(char c)
 {
+       if (!cons_has_init)
+               return;
        qiwrite(cons_q, &c, sizeof(char));
 }