[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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



On Thu, 4 Dec 2025, Grygorii Strashko wrote:
> From: Grygorii Strashko <grygorii_strashko@xxxxxxxx>
> 
> 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@xxxxxxxx>

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@xxxxxxx>
---
 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




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.