[XEN][PATCH] console/consoleio: account for xen serial input focus during write

Grygorii Strashko posted 1 patch 2 months, 1 week ago
Patches applied successfully (tree, apply log)
git fetch https://gitlab.com/xen-project/patchew/xen tags/patchew/20251204233211.980862-1-grygorii._5Fstrashko@epam.com
xen/drivers/char/console.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
[XEN][PATCH] console/consoleio: account for xen serial input focus during write
Posted by Grygorii Strashko 2 months, 1 week ago
From: Grygorii Strashko <grygorii_strashko@epam.com>

When 2 or more domains are created and:
- one is hwdom with "hvc0" (console_io) console
- other DomUs with vpl011 or "hvc0" (console_io) console
console output from hwdom may mix with output from other domains.

Example:
[    2.288816] Key type id_legacy registered
[    2.291894] n(XEN) DOM1: [    1.016950] DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA32 pool for atomic allocations
fs4filelayout_init: NFSv4 File Layout Driver Registering...
(XEN) DOM1: [    1.018846] audit: initializing netlink subsys (disabled)

This happens because for hwdom the console output is produced by domain and
handled by Xen as stream of chars, which can be interrupted when hwdom is
scheduled out and so, cause console output mix.
The Xen consoleio code trying to mimic serial HW behavior for hwdom
unconditionally by sending available data to serial HW on arrival.
Xen consoleio code does not account for Xen console input focus, comparing
to emulated serial hw, like vpl011, which does the same for domain with
active Xen console input focus only.

Switching console input focus to Xen improves situation, but not enough.

This patch changes consoleio code to account for domain with active Xen
console input focus - console output will be sent directly to serial HW
only if domain has active Xen console input focus. For other domains -
console output will be buffered and sync on per-line basis.

Example output:
(d2) [    4.263417] Key type id_legacy registered
(XEN) DOM1: [    4.658080] Advanced Linux Sound Architecture Driver Initialized.
(d2) [    4.277824] nfs4filelayout_init: NFSv4 File Layout Driver Registering...

Signed-off-by: Grygorii Strashko <grygorii_strashko@epam.com>
---
This causes random multi-domain tests failures due to inter-domain console
mixing which breaks console parsing checks.

 xen/drivers/char/console.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c
index a99605103552..391cefc1a7c6 100644
--- a/xen/drivers/char/console.c
+++ b/xen/drivers/char/console.c
@@ -733,6 +733,8 @@ static long guest_console_write(XEN_GUEST_HANDLE_PARAM(char) buffer,
 
     while ( count > 0 )
     {
+        struct domain *input;
+
         if ( kcount && hypercall_preempt_check() )
             return hypercall_create_continuation(
                 __HYPERVISOR_console_io, "iih",
@@ -742,7 +744,9 @@ 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 ( cd == input )
         {
             /* Use direct console output as it could be interactive */
             nrspin_lock_irq(&console_lock);
@@ -783,6 +787,8 @@ static long guest_console_write(XEN_GUEST_HANDLE_PARAM(char) buffer,
             spin_unlock(&cons->lock);
         }
 
+        console_put_domain(input);
+
         guest_handle_add_offset(buffer, kcount);
         count -= kcount;
     }
-- 
2.34.1
Re: [XEN][PATCH] console/consoleio: account for xen serial input focus during write
Posted by Stefano Stabellini 1 month ago
On Thu, 4 Dec 2025, Grygorii Strashko wrote:
> From: Grygorii Strashko <grygorii_strashko@epam.com>
> 
> When 2 or more domains are created and:
> - one is hwdom with "hvc0" (console_io) console
> - other DomUs with vpl011 or "hvc0" (console_io) console
> console output from hwdom may mix with output from other domains.
> 
> Example:
> [    2.288816] Key type id_legacy registered
> [    2.291894] n(XEN) DOM1: [    1.016950] DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA32 pool for atomic allocations
> fs4filelayout_init: NFSv4 File Layout Driver Registering...
> (XEN) DOM1: [    1.018846] audit: initializing netlink subsys (disabled)
> 
> This happens because for hwdom the console output is produced by domain and
> handled by Xen as stream of chars, which can be interrupted when hwdom is
> scheduled out and so, cause console output mix.
> The Xen consoleio code trying to mimic serial HW behavior for hwdom
> unconditionally by sending available data to serial HW on arrival.
> Xen consoleio code does not account for Xen console input focus, comparing
> to emulated serial hw, like vpl011, which does the same for domain with
> active Xen console input focus only.
> 
> Switching console input focus to Xen improves situation, but not enough.
> 
> This patch changes consoleio code to account for domain with active Xen
> console input focus - console output will be sent directly to serial HW
> only if domain has active Xen console input focus. For other domains -
> console output will be buffered and sync on per-line basis.
> 
> Example output:
> (d2) [    4.263417] Key type id_legacy registered
> (XEN) DOM1: [    4.658080] Advanced Linux Sound Architecture Driver Initialized.
> (d2) [    4.277824] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
> 
> Signed-off-by: Grygorii Strashko <grygorii_strashko@epam.com>

I independently wrote this patch which also supports console reads.
Sorry about the mixed messages.

---


xen/console: handle multiple domains using console_io hypercalls

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.

Signed-off-by: Stefano Stabellini <stefano.stabellini@amd.com>
---
 xen/drivers/char/console.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c
index dcc31170f2..826bee3848 100644
--- a/xen/drivers/char/console.c
+++ b/xen/drivers/char/console.c
@@ -729,6 +729,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 )
     {
@@ -741,17 +742,26 @@ 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)
         {
+            if ( cd->pbuf_idx )
+            {
+                cd->pbuf[cd->pbuf_idx] = '\0';
+                console_send(cd->pbuf, cd->pbuf_idx + 1, flags);
+                cd->pbuf_idx = 0;
+            }
             /* Use direct console output as it could be interactive */
             nrspin_lock_irq(&console_lock);
             console_send(kbuf, kcount, flags);
             nrspin_unlock_irq(&console_lock);
+            console_put_domain(input);
         }
         else
         {
             char *kin = kbuf, *kout = kbuf, c;
 
+            console_put_domain(input);
             /* Strip non-printable characters */
             do
             {
@@ -793,6 +803,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 )
@@ -813,6 +824,13 @@ long do_console_io(
         if ( count > INT_MAX )
             break;
 
+        d = console_get_domain();
+        if ( d != current->domain )
+        {
+            console_put_domain(d);
+            return 0;
+        }
+
         rc = 0;
         while ( (serial_rx_cons != serial_rx_prod) && (rc < count) )
         {
@@ -824,12 +842,14 @@ long do_console_io(
                 len = count - rc;
             if ( copy_to_guest_offset(buffer, rc, &serial_rx_ring[idx], len) )
             {
+                console_put_domain(d);
                 rc = -EFAULT;
                 break;
             }
             rc += len;
             serial_rx_cons += len;
         }
+        console_put_domain(d);
         break;
     default:
         rc = -ENOSYS;
-- 
2.25.1
Re: [XEN][PATCH] console/consoleio: account for xen serial input focus during write
Posted by Jan Beulich 4 weeks ago
On 09.01.2026 23:35, Stefano Stabellini wrote:
> I independently wrote this patch which also supports console reads.
> Sorry about the mixed messages.
> 
> ---
> 
> 
> xen/console: handle multiple domains using console_io hypercalls
> 
> 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.
> 
> Signed-off-by: Stefano Stabellini <stefano.stabellini@amd.com>
> ---
>  xen/drivers/char/console.c | 22 +++++++++++++++++++++-
>  1 file changed, 21 insertions(+), 1 deletion(-)
> 
> diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c
> index dcc31170f2..826bee3848 100644
> --- a/xen/drivers/char/console.c
> +++ b/xen/drivers/char/console.c
> @@ -729,6 +729,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 )
>      {
> @@ -741,17 +742,26 @@ 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)

Nit: Style (losing blanks).

>          {
> +            if ( cd->pbuf_idx )
> +            {
> +                cd->pbuf[cd->pbuf_idx] = '\0';
> +                console_send(cd->pbuf, cd->pbuf_idx + 1, flags);
> +                cd->pbuf_idx = 0;
> +            }

What is pbuf_idx? I can't find any such field in present staging. With that it
is also unclear what is actually being done here.

In any event I don't think you want to print/send the trailing nul char that
you insert. With that (and with console_send() taking the length anyway) it's
further unclear why the nul needs inserting in the first place (and thus, as
it looks, risking a buffer overrun).

> @@ -793,6 +803,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 )
> @@ -813,6 +824,13 @@ long do_console_io(
>          if ( count > INT_MAX )
>              break;
>  
> +        d = console_get_domain();
> +        if ( d != current->domain )
> +        {
> +            console_put_domain(d);



> +            return 0;
> +        }
> +
>          rc = 0;
>          while ( (serial_rx_cons != serial_rx_prod) && (rc < count) )
>          {
> @@ -824,12 +842,14 @@ long do_console_io(
>                  len = count - rc;
>              if ( copy_to_guest_offset(buffer, rc, &serial_rx_ring[idx], len) )
>              {
> +                console_put_domain(d);
>                  rc = -EFAULT;
>                  break;
>              }
>              rc += len;
>              serial_rx_cons += len;
>          }
> +        console_put_domain(d);
>          break;
>      default:
>          rc = -ENOSYS;

Hmm, this looks insufficient to me. Unconsumed input at the point focus switches
should not blindly go to the next domain. It was intended for what was the focus
at the time of typing.

Jan
Re: [XEN][PATCH] console/consoleio: account for xen serial input focus during write
Posted by Jason Andryuk 1 month, 2 weeks ago
On 2025-12-04 18:32, Grygorii Strashko wrote:
> From: Grygorii Strashko <grygorii_strashko@epam.com>
> 
> When 2 or more domains are created and:
> - one is hwdom with "hvc0" (console_io) console
> - other DomUs with vpl011 or "hvc0" (console_io) console
> console output from hwdom may mix with output from other domains.
> 
> Example:
> [    2.288816] Key type id_legacy registered
> [    2.291894] n(XEN) DOM1: [    1.016950] DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA32 pool for atomic allocations
> fs4filelayout_init: NFSv4 File Layout Driver Registering...
> (XEN) DOM1: [    1.018846] audit: initializing netlink subsys (disabled)
> 
> This happens because for hwdom the console output is produced by domain and
> handled by Xen as stream of chars, which can be interrupted when hwdom is
> scheduled out and so, cause console output mix.
> The Xen consoleio code trying to mimic serial HW behavior for hwdom
> unconditionally by sending available data to serial HW on arrival.
> Xen consoleio code does not account for Xen console input focus, comparing
> to emulated serial hw, like vpl011, which does the same for domain with
> active Xen console input focus only.
> 
> Switching console input focus to Xen improves situation, but not enough.
> 
> This patch changes consoleio code to account for domain with active Xen
> console input focus - console output will be sent directly to serial HW
> only if domain has active Xen console input focus. For other domains -
> console output will be buffered and sync on per-line basis.
> 
> Example output:
> (d2) [    4.263417] Key type id_legacy registered
> (XEN) DOM1: [    4.658080] Advanced Linux Sound Architecture Driver Initialized.
> (d2) [    4.277824] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
> 
> Signed-off-by: Grygorii Strashko <grygorii_strashko@epam.com>
> ---
> This causes random multi-domain tests failures due to inter-domain console
> mixing which breaks console parsing checks.

Part of the motivation here is that in a downstream, I've enabled domUs 
to use the consoleio hypercalls with Hyperlunch to remove dependency on 
xenconsoled.  Grygorii can confirm if it also affects ARM sometimes.

> 
>   xen/drivers/char/console.c | 8 +++++++-
>   1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c
> index a99605103552..391cefc1a7c6 100644
> --- a/xen/drivers/char/console.c
> +++ b/xen/drivers/char/console.c
> @@ -733,6 +733,8 @@ static long guest_console_write(XEN_GUEST_HANDLE_PARAM(char) buffer,
>   
>       while ( count > 0 )
>       {
> +        struct domain *input;
> +
>           if ( kcount && hypercall_preempt_check() )
>               return hypercall_create_continuation(
>                   __HYPERVISOR_console_io, "iih",
> @@ -742,7 +744,9 @@ 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();
> +

Maybe remove this blank line?

> +        if ( cd == input )
>           {
>               /* Use direct console output as it could be interactive */
>               nrspin_lock_irq(&console_lock);
> @@ -783,6 +787,8 @@ static long guest_console_write(XEN_GUEST_HANDLE_PARAM(char) buffer,

In between the hunks is:
     guest_printk(cd, XENLOG_G_DEBUG "%s%s\n", cons->buf, kbuf);

So a background dom0 would get a d0 prefix and print at debug level.

For ARM, vpl011_write_data_xen() does:

if ( d == input )
     printk("%s", intf->out);
else
     printk("DOM%u: %s", d->domain_id, intf->out);

I think d0: is okay for background printing, but we'd need to up the log 
level for at least hardware domain.  Maybe we want a properly to control 
the level for each domain?

I think the changes made in this patch make sense.

Thanks,
Jason

>               spin_unlock(&cons->lock);
>           }
>   
> +        console_put_domain(input);
> +
>           guest_handle_add_offset(buffer, kcount);
>           count -= kcount;
>       }
Re: [XEN][PATCH] console/consoleio: account for xen serial input focus during write
Posted by Jan Beulich 2 months ago
On 05.12.2025 00:32, Grygorii Strashko wrote:
> From: Grygorii Strashko <grygorii_strashko@epam.com>
> 
> When 2 or more domains are created and:
> - one is hwdom with "hvc0" (console_io) console
> - other DomUs with vpl011 or "hvc0" (console_io) console
> console output from hwdom may mix with output from other domains.
> 
> Example:
> [    2.288816] Key type id_legacy registered
> [    2.291894] n(XEN) DOM1: [    1.016950] DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA32 pool for atomic allocations
> fs4filelayout_init: NFSv4 File Layout Driver Registering...
> (XEN) DOM1: [    1.018846] audit: initializing netlink subsys (disabled)
> 
> This happens because for hwdom the console output is produced by domain and
> handled by Xen as stream of chars, which can be interrupted when hwdom is
> scheduled out and so, cause console output mix.
> The Xen consoleio code trying to mimic serial HW behavior for hwdom
> unconditionally by sending available data to serial HW on arrival.
> Xen consoleio code does not account for Xen console input focus, comparing
> to emulated serial hw, like vpl011, which does the same for domain with
> active Xen console input focus only.
> 
> Switching console input focus to Xen improves situation, but not enough.
> 
> This patch changes consoleio code to account for domain with active Xen
> console input focus - console output will be sent directly to serial HW
> only if domain has active Xen console input focus. For other domains -
> console output will be buffered and sync on per-line basis.
> 
> Example output:
> (d2) [    4.263417] Key type id_legacy registered
> (XEN) DOM1: [    4.658080] Advanced Linux Sound Architecture Driver Initialized.
> (d2) [    4.277824] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
> 
> Signed-off-by: Grygorii Strashko <grygorii_strashko@epam.com>
> ---
> This causes random multi-domain tests failures due to inter-domain console
> mixing which breaks console parsing checks.

This remark reads as if "here's a patch, but it breaks things". Instead of
merely "This", did you maybe mean "The original behavior" or some such?

Jan
Re: [XEN][PATCH] console/consoleio: account for xen serial input focus during write
Posted by Grygorii Strashko 2 months ago

On 05.12.25 09:39, Jan Beulich wrote:
> On 05.12.2025 00:32, Grygorii Strashko wrote:
>> From: Grygorii Strashko <grygorii_strashko@epam.com>
>>
>> When 2 or more domains are created and:
>> - one is hwdom with "hvc0" (console_io) console
>> - other DomUs with vpl011 or "hvc0" (console_io) console
>> console output from hwdom may mix with output from other domains.
>>
>> Example:
>> [    2.288816] Key type id_legacy registered
>> [    2.291894] n(XEN) DOM1: [    1.016950] DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA32 pool for atomic allocations
>> fs4filelayout_init: NFSv4 File Layout Driver Registering...
>> (XEN) DOM1: [    1.018846] audit: initializing netlink subsys (disabled)
>>
>> This happens because for hwdom the console output is produced by domain and
>> handled by Xen as stream of chars, which can be interrupted when hwdom is
>> scheduled out and so, cause console output mix.
>> The Xen consoleio code trying to mimic serial HW behavior for hwdom
>> unconditionally by sending available data to serial HW on arrival.
>> Xen consoleio code does not account for Xen console input focus, comparing
>> to emulated serial hw, like vpl011, which does the same for domain with
>> active Xen console input focus only.
>>
>> Switching console input focus to Xen improves situation, but not enough.
>>
>> This patch changes consoleio code to account for domain with active Xen
>> console input focus - console output will be sent directly to serial HW
>> only if domain has active Xen console input focus. For other domains -
>> console output will be buffered and sync on per-line basis.
>>
>> Example output:
>> (d2) [    4.263417] Key type id_legacy registered
>> (XEN) DOM1: [    4.658080] Advanced Linux Sound Architecture Driver Initialized.
>> (d2) [    4.277824] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
>>
>> Signed-off-by: Grygorii Strashko <grygorii_strashko@epam.com>
>> ---
>> This causes random multi-domain tests failures due to inter-domain console
>> mixing which breaks console parsing checks.
> 
> This remark reads as if "here's a patch, but it breaks things". Instead of
> merely "This", did you maybe mean "The original behavior" or some such?

Right.

"
The original behavior causes random multi-domain tests failures due to inter-domain console
mixing which breaks console parsing checks.
"

-- 
Best regards,
-grygorii