Enable dom0less guests on ARM to use console_io hypercalls:
- set input_allow = true for dom0less domains
- update the in-code comment in console.c
- prioritize the VUART check to retain the same behavior as today
Signed-off-by: Stefano Stabellini <stefano.stabellini@amd.com>
---
xen/common/device-tree/dom0less-build.c | 2 ++
xen/drivers/char/console.c | 16 ++++++++++------
2 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/xen/common/device-tree/dom0less-build.c b/xen/common/device-tree/dom0less-build.c
index 840d14419d..cb7026fa7e 100644
--- a/xen/common/device-tree/dom0less-build.c
+++ b/xen/common/device-tree/dom0less-build.c
@@ -829,6 +829,8 @@ static int __init construct_domU(struct kernel_info *kinfo,
rangeset_destroy(kinfo->xen_reg_assigned);
+ d->console->input_allowed = true;
+
return rc;
}
diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c
index d3ce925131..7f0c3d8376 100644
--- a/xen/drivers/char/console.c
+++ b/xen/drivers/char/console.c
@@ -610,11 +610,20 @@ static void __serial_rx(char c)
if ( ACCESS_ONCE(console_rx) == 0 )
return handle_keypress(c, false);
+ /* Includes an is_focus_domain() check. */
d = console_get_domain();
if ( !d )
return;
- if ( is_hardware_domain(d) )
+#ifdef CONFIG_SBSA_VUART_CONSOLE
+ /* Prioritize vpl011 if enabled for this domain */
+ if ( d->arch.vpl011.base_addr )
+ {
+ /* Deliver input to the emulated UART. */
+ rc = vpl011_rx_char_xen(d, c);
+ }
+ else
+#endif
{
unsigned long flags;
@@ -633,11 +642,6 @@ static void __serial_rx(char c)
*/
send_guest_domain_virq(d, VIRQ_CONSOLE);
}
-#ifdef CONFIG_SBSA_VUART_CONSOLE
- else
- /* Deliver input to the emulated UART. */
- rc = vpl011_rx_char_xen(d, c);
-#endif
if ( consoled_is_enabled() )
/* Deliver input to the PV shim console. */
--
2.25.1
On Wed, Feb 04, 2026 at 03:37:12PM -0800, Stefano Stabellini wrote:
> Enable dom0less guests on ARM to use console_io hypercalls:
> - set input_allow = true for dom0less domains
> - update the in-code comment in console.c
> - prioritize the VUART check to retain the same behavior as today
>
> Signed-off-by: Stefano Stabellini <stefano.stabellini@amd.com>
The code looks good, just one remark wrt prioritizing VUART check.
> ---
> xen/common/device-tree/dom0less-build.c | 2 ++
> xen/drivers/char/console.c | 16 ++++++++++------
> 2 files changed, 12 insertions(+), 6 deletions(-)
>
> diff --git a/xen/common/device-tree/dom0less-build.c b/xen/common/device-tree/dom0less-build.c
> index 840d14419d..cb7026fa7e 100644
> --- a/xen/common/device-tree/dom0less-build.c
> +++ b/xen/common/device-tree/dom0less-build.c
> @@ -829,6 +829,8 @@ static int __init construct_domU(struct kernel_info *kinfo,
>
> rangeset_destroy(kinfo->xen_reg_assigned);
>
> + d->console->input_allowed = true;
> +
> return rc;
> }
>
> diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c
> index d3ce925131..7f0c3d8376 100644
> --- a/xen/drivers/char/console.c
> +++ b/xen/drivers/char/console.c
> @@ -610,11 +610,20 @@ static void __serial_rx(char c)
> if ( ACCESS_ONCE(console_rx) == 0 )
> return handle_keypress(c, false);
>
> + /* Includes an is_focus_domain() check. */
> d = console_get_domain();
> if ( !d )
> return;
>
> - if ( is_hardware_domain(d) )
Hardware domain on x86 may have an emulated UART (not in upstream, through,
I need to send v8 for NS16550 series...). The patch which illustrates the
idea:
https://lore.kernel.org/xen-devel/20250908211149.279143-2-dmukhin@ford.com/
So this code (hopefully soon) will need adjustment again.
I would update the code to something like:
if ( is_hardware_domain(d) && !domain_has_vuart(d) )
{
// handle hardware domain
}
#ifdef CONFIG_SBSA_VUART_CONSOLE
else if ( domain_has_vuart(d) )
/* Deliver input to the emulated UART. */
rc = vpl011_rx_char_xen(d, c);
#endif
But domain_has_vuart() needs to be defined for all architectures
(currently it is hidden in arch/arm/vuart.c).
Or perhaps it is possible to postpone the change?
What do you think?
> +#ifdef CONFIG_SBSA_VUART_CONSOLE
> + /* Prioritize vpl011 if enabled for this domain */
> + if ( d->arch.vpl011.base_addr )
> + {
> + /* Deliver input to the emulated UART. */
> + rc = vpl011_rx_char_xen(d, c);
> + }
> + else
> +#endif
> {
> unsigned long flags;
>
> @@ -633,11 +642,6 @@ static void __serial_rx(char c)
> */
> send_guest_domain_virq(d, VIRQ_CONSOLE);
> }
> -#ifdef CONFIG_SBSA_VUART_CONSOLE
> - else
> - /* Deliver input to the emulated UART. */
> - rc = vpl011_rx_char_xen(d, c);
> -#endif
>
> if ( consoled_is_enabled() )
> /* Deliver input to the PV shim console. */
> --
> 2.25.1
>
>
On Wed, 4 Feb 2026, dmukhin@xen.org wrote:
> On Wed, Feb 04, 2026 at 03:37:12PM -0800, Stefano Stabellini wrote:
> > Enable dom0less guests on ARM to use console_io hypercalls:
> > - set input_allow = true for dom0less domains
> > - update the in-code comment in console.c
> > - prioritize the VUART check to retain the same behavior as today
> >
> > Signed-off-by: Stefano Stabellini <stefano.stabellini@amd.com>
>
> The code looks good, just one remark wrt prioritizing VUART check.
>
> > ---
> > xen/common/device-tree/dom0less-build.c | 2 ++
> > xen/drivers/char/console.c | 16 ++++++++++------
> > 2 files changed, 12 insertions(+), 6 deletions(-)
> >
> > diff --git a/xen/common/device-tree/dom0less-build.c b/xen/common/device-tree/dom0less-build.c
> > index 840d14419d..cb7026fa7e 100644
> > --- a/xen/common/device-tree/dom0less-build.c
> > +++ b/xen/common/device-tree/dom0less-build.c
> > @@ -829,6 +829,8 @@ static int __init construct_domU(struct kernel_info *kinfo,
> >
> > rangeset_destroy(kinfo->xen_reg_assigned);
> >
> > + d->console->input_allowed = true;
> > +
> > return rc;
> > }
> >
> > diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c
> > index d3ce925131..7f0c3d8376 100644
> > --- a/xen/drivers/char/console.c
> > +++ b/xen/drivers/char/console.c
> > @@ -610,11 +610,20 @@ static void __serial_rx(char c)
> > if ( ACCESS_ONCE(console_rx) == 0 )
> > return handle_keypress(c, false);
> >
> > + /* Includes an is_focus_domain() check. */
> > d = console_get_domain();
> > if ( !d )
> > return;
> >
> > - if ( is_hardware_domain(d) )
>
> Hardware domain on x86 may have an emulated UART (not in upstream, through,
> I need to send v8 for NS16550 series...). The patch which illustrates the
> idea:
> https://lore.kernel.org/xen-devel/20250908211149.279143-2-dmukhin@ford.com/
>
> So this code (hopefully soon) will need adjustment again.
>
> I would update the code to something like:
>
>
>
> if ( is_hardware_domain(d) && !domain_has_vuart(d) )
> {
> // handle hardware domain
> }
> #ifdef CONFIG_SBSA_VUART_CONSOLE
> else if ( domain_has_vuart(d) )
> /* Deliver input to the emulated UART. */
> rc = vpl011_rx_char_xen(d, c);
> #endif
>
>
>
> But domain_has_vuart() needs to be defined for all architectures
> (currently it is hidden in arch/arm/vuart.c).
>
> Or perhaps it is possible to postpone the change?
This change is needed to avoid regressions on ARM.
However, while I wouldn't be surprised if we need a change here for your
upcoming patch series, at the same time at the moment I don't see why
this check wouldn't work as it is for you as well.
On x86, CONFIG_SBSA_VUART_CONSOLE will never be set. It is OK to do this
first:
#ifdef CONFIG_SBSA_VUART_CONSOLE
/* Prioritize vpl011 if enabled for this domain */
if ( d->arch.vpl011.base_addr )
{
/* Deliver input to the emulated UART. */
rc = vpl011_rx_char_xen(d, c);
}
else
#endif
It shouldn't hurt. The is_hardware_domain() check is also not necessary
anymore because any necessary check would be part of this check above:
d = console_get_domain();
if ( !d )
return;
So I am guessing that your series might actually leave this code
unchanged and instead might modify console_get_domain() or
max_console_rx.
> > +#ifdef CONFIG_SBSA_VUART_CONSOLE
> > + /* Prioritize vpl011 if enabled for this domain */
> > + if ( d->arch.vpl011.base_addr )
> > + {
> > + /* Deliver input to the emulated UART. */
> > + rc = vpl011_rx_char_xen(d, c);
> > + }
> > + else
> > +#endif
> > {
> > unsigned long flags;
> >
> > @@ -633,11 +642,6 @@ static void __serial_rx(char c)
> > */
> > send_guest_domain_virq(d, VIRQ_CONSOLE);
> > }
> > -#ifdef CONFIG_SBSA_VUART_CONSOLE
> > - else
> > - /* Deliver input to the emulated UART. */
> > - rc = vpl011_rx_char_xen(d, c);
> > -#endif
> >
> > if ( consoled_is_enabled() )
> > /* Deliver input to the PV shim console. */
> > --
> > 2.25.1
> >
> >
>
On Thu, Feb 05, 2026 at 02:09:07PM -0800, Stefano Stabellini wrote:
> On Wed, 4 Feb 2026, dmukhin@xen.org wrote:
> > On Wed, Feb 04, 2026 at 03:37:12PM -0800, Stefano Stabellini wrote:
> > > Enable dom0less guests on ARM to use console_io hypercalls:
> > > - set input_allow = true for dom0less domains
> > > - update the in-code comment in console.c
> > > - prioritize the VUART check to retain the same behavior as today
> > >
> > > Signed-off-by: Stefano Stabellini <stefano.stabellini@amd.com>
> >
> > The code looks good, just one remark wrt prioritizing VUART check.
> >
> > > ---
> > > xen/common/device-tree/dom0less-build.c | 2 ++
> > > xen/drivers/char/console.c | 16 ++++++++++------
> > > 2 files changed, 12 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/xen/common/device-tree/dom0less-build.c b/xen/common/device-tree/dom0less-build.c
> > > index 840d14419d..cb7026fa7e 100644
> > > --- a/xen/common/device-tree/dom0less-build.c
> > > +++ b/xen/common/device-tree/dom0less-build.c
> > > @@ -829,6 +829,8 @@ static int __init construct_domU(struct kernel_info *kinfo,
> > >
> > > rangeset_destroy(kinfo->xen_reg_assigned);
> > >
> > > + d->console->input_allowed = true;
> > > +
> > > return rc;
> > > }
> > >
> > > diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c
> > > index d3ce925131..7f0c3d8376 100644
> > > --- a/xen/drivers/char/console.c
> > > +++ b/xen/drivers/char/console.c
> > > @@ -610,11 +610,20 @@ static void __serial_rx(char c)
> > > if ( ACCESS_ONCE(console_rx) == 0 )
> > > return handle_keypress(c, false);
> > >
> > > + /* Includes an is_focus_domain() check. */
> > > d = console_get_domain();
> > > if ( !d )
> > > return;
> > >
> > > - if ( is_hardware_domain(d) )
> >
> > Hardware domain on x86 may have an emulated UART (not in upstream, through,
> > I need to send v8 for NS16550 series...). The patch which illustrates the
> > idea:
> > https://lore.kernel.org/xen-devel/20250908211149.279143-2-dmukhin@ford.com/
> >
> > So this code (hopefully soon) will need adjustment again.
> >
> > I would update the code to something like:
> >
> >
> >
> > if ( is_hardware_domain(d) && !domain_has_vuart(d) )
> > {
> > // handle hardware domain
> > }
> > #ifdef CONFIG_SBSA_VUART_CONSOLE
> > else if ( domain_has_vuart(d) )
> > /* Deliver input to the emulated UART. */
> > rc = vpl011_rx_char_xen(d, c);
> > #endif
> >
> >
> >
> > But domain_has_vuart() needs to be defined for all architectures
> > (currently it is hidden in arch/arm/vuart.c).
> >
> > Or perhaps it is possible to postpone the change?
>
> This change is needed to avoid regressions on ARM.
Oh, I see.
>
> However, while I wouldn't be surprised if we need a change here for your
> upcoming patch series, at the same time at the moment I don't see why
> this check wouldn't work as it is for you as well.
>
> On x86, CONFIG_SBSA_VUART_CONSOLE will never be set. It is OK to do this
> first:
>
> #ifdef CONFIG_SBSA_VUART_CONSOLE
> /* Prioritize vpl011 if enabled for this domain */
> if ( d->arch.vpl011.base_addr )
> {
> /* Deliver input to the emulated UART. */
> rc = vpl011_rx_char_xen(d, c);
> }
> else
> #endif
>
> It shouldn't hurt. The is_hardware_domain() check is also not necessary
> anymore because any necessary check would be part of this check above:
>
> d = console_get_domain();
> if ( !d )
> return;
>
> So I am guessing that your series might actually leave this code
> unchanged and instead might modify console_get_domain() or
> max_console_rx.
I think I did experiment w/ processing vUART before hardware domain
locally when debugging NS16550 emulator with dom0 PVH...
Thanks for explanations!
Please consider:
Reviewed-by: Denis Mukhin <dmukhin@ford.com>
>
>
>
> > > +#ifdef CONFIG_SBSA_VUART_CONSOLE
> > > + /* Prioritize vpl011 if enabled for this domain */
> > > + if ( d->arch.vpl011.base_addr )
> > > + {
> > > + /* Deliver input to the emulated UART. */
> > > + rc = vpl011_rx_char_xen(d, c);
> > > + }
> > > + else
> > > +#endif
> > > {
> > > unsigned long flags;
> > >
> > > @@ -633,11 +642,6 @@ static void __serial_rx(char c)
> > > */
> > > send_guest_domain_virq(d, VIRQ_CONSOLE);
> > > }
> > > -#ifdef CONFIG_SBSA_VUART_CONSOLE
> > > - else
> > > - /* Deliver input to the emulated UART. */
> > > - rc = vpl011_rx_char_xen(d, c);
> > > -#endif
> > >
> > > if ( consoled_is_enabled() )
> > > /* Deliver input to the PV shim console. */
> > > --
> > > 2.25.1
> > >
> > >
> >
© 2016 - 2026 Red Hat, Inc.