Today Ctrl-AAA is used to switch between Xen and Dom0. Extend the mechanism to allow for switching between Xen, Dom0, and any of the initial DomU created from Xen alongside Dom0 out of information provided via device tree.
Rename xen_rx to console_rx to match the new behavior. Clarify existing comment about "notify the guest", making it clear that it is only about the hardware domain. Signed-off-by: Stefano Stabellini <stefa...@xilinx.com> CC: andrew.coop...@citrix.com CC: george.dun...@eu.citrix.com CC: ian.jack...@eu.citrix.com CC: jbeul...@suse.com CC: konrad.w...@oracle.com CC: t...@xen.org CC: wei.l...@citrix.com --- Changes in v4: - handle console_rx == 0 in console_input_domain - use rcu_lock_by_domain instead of get_domain_by_id - handle the case where the returned domain is NULL - send_global_virq(VIRQ_CONSOLE) only when chars are for Dom0 - make console_rx unsigned int - fix comment - code readability improvement - fix opt_conswitch[1] == 'x' case - move console_input_domain to next patch Changes in v3: - only call vpl011 functions ifdef CONFIG_SBSA_VUART_CONSOLE - add blank line and spaces - remove xen_rx from print messages - rename xen_rx to console_rx - keep switch_serial_input() at boot - add better comments - fix existing comment - add warning if no guests console/uart is available - add console_input_domain function Changes in v2: - only call vpl011_rx_char if the vpl011 has been initialized --- xen/drivers/char/console.c | 73 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 59 insertions(+), 14 deletions(-) diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c index 3b75f7a..0808bac 100644 --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -31,10 +31,13 @@ #include <xen/early_printk.h> #include <xen/warning.h> #include <xen/pv_console.h> +#include <asm/setup.h> #ifdef CONFIG_X86 #include <xen/consoled.h> #include <asm/guest.h> +#else +#include <asm/vpl011.h> #endif /* console: comma-separated list of console outputs. */ @@ -391,31 +394,73 @@ static void dump_console_ring_key(unsigned char key) free_xenheap_pages(buf, order); } -/* CTRL-<switch_char> switches input direction between Xen and DOM0. */ +/* + * CTRL-<switch_char> switches input direction between Xen, Dom0 and + * DomUs. + */ #define switch_code (opt_conswitch[0]-'a'+1) -static int __read_mostly xen_rx = 1; /* FALSE => input passed to domain 0. */ +/* + * console_rx=0 => input to xen + * console_rx=1 => input to dom0 + * console_rx=N => input dom(N-1) + */ +static unsigned int __read_mostly console_rx = 0; static void switch_serial_input(void) { - static char *input_str[2] = { "DOM0", "Xen" }; - xen_rx = !xen_rx; - printk("*** Serial input -> %s", input_str[xen_rx]); + if ( console_rx++ == max_init_domid + 1 ) + console_rx = 0; + + if ( !console_rx ) + printk("*** Serial input to Xen"); + else + printk("*** Serial input to DOM%d", console_rx - 1); + if ( switch_code ) - printk(" (type 'CTRL-%c' three times to switch input to %s)", - opt_conswitch[0], input_str[!xen_rx]); + printk(" (type 'CTRL-%c' three times to switch input)", + opt_conswitch[0]); printk("\n"); } static void __serial_rx(char c, struct cpu_user_regs *regs) { - if ( xen_rx ) + if ( console_rx == 0 ) return handle_keypress(c, regs); - /* Deliver input to guest buffer, unless it is already full. */ - if ( (serial_rx_prod-serial_rx_cons) != SERIAL_RX_SIZE ) - serial_rx_ring[SERIAL_RX_MASK(serial_rx_prod++)] = c; - /* Always notify the guest: prevents receive path from getting stuck. */ - send_global_virq(VIRQ_CONSOLE); + if ( console_rx == 1 ) + { + /* Deliver input to hardware domain, unless it is already full. */ + if ( (serial_rx_prod - serial_rx_cons) != SERIAL_RX_SIZE ) + serial_rx_ring[SERIAL_RX_MASK(serial_rx_prod++)] = c; + + /* + * Always notify the hardware domain: prevents receive path from + * getting stuck. + */ + send_global_virq(VIRQ_CONSOLE); + } +#ifdef CONFIG_SBSA_VUART_CONSOLE + else + { + struct domain *d = rcu_lock_domain_by_any_id(console_rx - 1); + + /* + * 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 && + !d->arch.vpl011.backend_in_domain && + d->arch.vpl011.backend.xen != NULL ) + vpl011_rx_char_xen(d, c); + else + printk("Cannot send chars to Dom%d: no UART available\n", + console_rx - 1); + + if ( d != NULL ) + rcu_unlock_domain(d); + } +#endif #ifdef CONFIG_X86 if ( pv_shim && pv_console ) @@ -943,7 +988,7 @@ void __init console_endboot(void) * a useful 'how to switch' message. */ if ( opt_conswitch[1] == 'x' ) - xen_rx = !xen_rx; + console_rx = max_init_domid + 1; register_keyhandler('w', dump_console_ring_key, "synchronously dump console ring buffer (dmesg)", 0); -- 1.9.1 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel