@@ -78,7 +78,7 @@ static void vpl011_write_data_xen(struct domain *d, uint8_t data)
unsigned long flags;
struct vpl011 *vpl011 = &d->arch.vpl011;
struct vpl011_xen_backend *intf = vpl011->backend.xen;
- struct domain *input = console_input_domain();
+ struct domain *input = console_get_domain();
VPL011_LOCK(d, flags);
@@ -123,8 +123,8 @@ static void vpl011_write_data_xen(struct domain *d, uint8_t data)
vpl011_update_interrupt_status(d);
VPL011_UNLOCK(d, flags);
- if ( input != NULL )
- rcu_unlock_domain(input);
+
+ console_put_domain(input);
}
/*
@@ -475,15 +475,18 @@ static unsigned int __read_mostly console_rx = 0;
#define max_console_rx (max_init_domid + 1)
-#ifdef CONFIG_SBSA_VUART_CONSOLE
-/* Make sure to rcu_unlock_domain after use */
-struct domain *console_input_domain(void)
+struct domain *console_get_domain(void)
{
if ( console_rx == 0 )
return NULL;
return rcu_lock_domain_by_id(console_rx - 1);
}
-#endif
+
+void console_put_domain(struct domain *d)
+{
+ if ( d )
+ rcu_unlock_domain(d);
+}
static void switch_serial_input(void)
{
@@ -529,14 +532,18 @@ static void switch_serial_input(void)
static void __serial_rx(char c)
{
+ struct domain *d;
int rc = 0;
- switch ( console_rx )
- {
- case 0:
+ if ( console_rx == 0 )
return handle_keypress(c, false);
- case 1:
+ d = console_get_domain();
+ if ( !d )
+ return;
+
+ if ( is_hardware_domain(d) )
+ {
/*
* Deliver input to the hardware domain buffer, unless it is
* already full.
@@ -549,23 +556,12 @@ 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_rx - 1);
-
- if ( d )
- {
- rc = vpl011_rx_char_xen(d, c);
- rcu_unlock_domain(d);
- }
-
- break;
- }
+ else
+ /* Deliver input to the emulated UART. */
+ rc = vpl011_rx_char_xen(d, c);
#endif
- }
#ifdef CONFIG_X86
if ( pv_shim && pv_console )
@@ -574,6 +570,8 @@ static void __serial_rx(char c)
if ( rc )
printk(KERN_ERR "d%pd: failed to process console input: %d\n", d, rc);
+
+ console_put_domain(d);
}
static void cf_check serial_rx(char c)
@@ -31,7 +31,8 @@ void console_end_sync(void);
void console_start_log_everything(void);
void console_end_log_everything(void);
-struct domain *console_input_domain(void);
+struct domain *console_get_domain(void);
+void console_put_domain(struct domain *d);
/*
* Steal output from the console. Returns +ve identifier, else -ve error.