|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v3] xen/console: handle multiple domains using console_io hypercalls
On Tue, 13 Jan 2026, Stefano Stabellini wrote:
> Allow multiple dom0less domains to use the console_io hypercalls to
> print to the console. Handle them in a similar way to vpl011: only the
> domain which has focus can read from the console. All domains can write
> to the console but the ones without focus have a prefix. In this case
> the prefix is applied by using guest_printk instead of printk or
> console_puts which is what the original code was already doing.
>
> When switching focus using Ctrl-AAA, discard any unread data in the
> input buffer. Input is read quickly and the user would be aware of it
> being slow or stuck as they use Ctrl-AAA to switch focus domain.
> In that situation, it is to be expected that the unread input is lost.
>
> The domain writes are buffered when the domain is not in focus. Push out
> the buffer when the domain enters focus.
>
> Add the console_lock around serial_rx_cons modifications to protect it
> against concurrent writes to it.
>
> Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxx>
Ping?
> ---
> Changes in v3:
> - move serial_rx_cons before printk
> - call console_put_domain earlier on CONSOLEIO_read
> - take console_lock earlier
> - add console_lock around serial_rx_cons modifications
>
> Changes in v2:
> - fix code style
> - pbuf_idx/idx after ada53067083e
> - don't add extra \0
> - clear input on console switch
> ---
> xen/drivers/char/console.c | 30 +++++++++++++++++++++++++++---
> 1 file changed, 27 insertions(+), 3 deletions(-)
>
> diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c
> index 2bdb4d5fb4..58c32f22ef 100644
> --- a/xen/drivers/char/console.c
> +++ b/xen/drivers/char/console.c
> @@ -577,6 +577,10 @@ static void console_switch_input(void)
>
> console_rx = next_rx;
> printk("*** Serial input to DOM%u", domid);
> + /* Don't let the next dom read the previous dom's unread data. */
> + nrspin_lock_irq(&console_lock);
> + serial_rx_cons = serial_rx_prod;
> + nrspin_unlock_irq(&console_lock);
> break;
> }
> }
> @@ -730,6 +734,7 @@ static long
> guest_console_write(XEN_GUEST_HANDLE_PARAM(char) buffer,
> unsigned int flags = opt_console_to_ring
> ? CONSOLE_ALL : CONSOLE_DEFAULT;
> struct domain *cd = current->domain;
> + struct domain *input;
>
> while ( count > 0 )
> {
> @@ -742,18 +747,28 @@ static long
> guest_console_write(XEN_GUEST_HANDLE_PARAM(char) buffer,
> if ( copy_from_guest(kbuf, buffer, kcount) )
> return -EFAULT;
>
> - if ( is_hardware_domain(cd) )
> + input = console_get_domain();
> + if ( input && cd == input )
> {
> - /* Use direct console output as it could be interactive */
> + struct domain_console *cons = cd->console;
> +
> nrspin_lock_irq(&console_lock);
> + if ( cons->idx )
> + {
> + console_send(cons->buf, cons->idx, flags);
> + cons->idx = 0;
> + }
> + /* Use direct console output as it could be interactive */
> console_send(kbuf, kcount, flags);
> nrspin_unlock_irq(&console_lock);
> + console_put_domain(input);
> }
> else
> {
> char *kin = kbuf, *kout = kbuf, c;
> struct domain_console *cons = cd->console;
>
> + console_put_domain(input);
> /* Strip non-printable characters */
> do
> {
> @@ -795,6 +810,7 @@ long do_console_io(
> {
> long rc;
> unsigned int idx, len;
> + struct domain *d;
>
> rc = xsm_console_io(XSM_OTHER, current->domain, cmd);
> if ( rc )
> @@ -815,6 +831,11 @@ long do_console_io(
> if ( count > INT_MAX )
> break;
>
> + d = console_get_domain();
> + console_put_domain(d);
> + if ( d != current->domain )
> + return 0;
> +
> rc = 0;
> while ( (serial_rx_cons != serial_rx_prod) && (rc < count) )
> {
> @@ -830,7 +851,10 @@ long do_console_io(
> break;
> }
> rc += len;
> - serial_rx_cons += len;
> + nrspin_lock_irq(&console_lock);
> + if ( serial_rx_cons != serial_rx_prod )
> + serial_rx_cons += len;
> + nrspin_unlock_irq(&console_lock);
> }
> break;
> default:
> --
> 2.25.1
>
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |