@@ -570,14 +570,16 @@ static void console_init_owner(void)
console_set_owner(domid);
}
-static void __serial_rx(char c)
+static void handle_keypress_in_domain(struct domain *d, char c)
{
- switch ( console_owner )
- {
- case DOMID_XEN:
- return handle_keypress(c, false);
+ int rc = 0;
- case 0:
+ /*
+ * Deliver input to the hardware domain buffer.
+ * NB: must be the first check: hardware domain may have emulated UART.
+ */
+ if ( d == hardware_domain )
+ {
/*
* Deliver input to the hardware domain buffer, unless it is
* already full.
@@ -590,34 +592,44 @@ static void __serial_rx(char c)
* getting stuck.
*/
send_global_virq(VIRQ_CONSOLE);
- break;
-
-#ifdef CONFIG_SBSA_VUART_CONSOLE
- default:
- {
- struct domain *d = rcu_lock_domain_by_id(console_owner);
-
- /*
- * If we have a properly initialized vpl011 console for the
- * domain, without a full PV ring to Dom0 (in that case input
- * comes from the PV ring), then send the character to it.
- */
- if ( d != NULL )
- vpl011_rx_char_xen(d, c);
- else
- printk("Cannot send chars to Dom%d: no UART available\n",
- console_owner);
-
- if ( d != NULL )
- rcu_unlock_domain(d);
-
- break;
}
+ /*
+ * Deliver input to the emulated UART.
+ */
+ else if ( domain_has_vuart(d) )
+ {
+#if defined(CONFIG_SBSA_VUART_CONSOLE)
+ rc = vpl011_rx_char_xen(d, c);
#endif
}
-
+ /*
+ * Deliver input to the PV shim console.
+ */
if ( consoled_is_enabled() )
- consoled_guest_tx(c);
+ rc = consoled_guest_tx(c);
+
+ if ( rc && rc != -ENODEV )
+ printk(KERN_WARNING "console input domain %d: not ready: %d\n",
+ d->domain_id, rc);
+}
+
+static void __serial_rx(char c)
+{
+ struct domain *d;
+
+ if ( console_owner == DOMID_XEN )
+ {
+ handle_keypress(c, false);
+ return;
+ }
+
+ d = rcu_lock_domain_console_owner();
+ if ( d == NULL )
+ return;
+
+ handle_keypress_in_domain(d, c);
+
+ rcu_unlock_domain(d);
}
static void cf_check serial_rx(char c)