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

[PATCH v10 3/5] xen/console: add locking for serial_rx ring buffer access


  • To: <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Stefano Stabellini <stefano.stabellini@xxxxxxx>
  • Date: Wed, 4 Feb 2026 15:37:10 -0800
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lists.xenproject.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0)
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=mqwBp4MnNYKS6IvAa9j+HIjyvIvt0WGP7tqhc7zOsLU=; b=ExoQGo4s3V/+PqVPPuHLz+5xsKbXQW+A8ESdkvieZ79cdcI1ulC6h64qt7YkFQM8rwz1uXESevV4wWhd1yrj1Nta7p/iOPymzf2Ns3j0hkregsT5mqqAT2p1fA55KxttkMdNay22fBqGaHZF7Yc2EXkroefHGOom+Sg9pJKobs8VdiDVtSlvLtoPny6NXwa/FyRA61L2L0WaCcWJWf1gjcO8U9qaev8W/TidkhKCUocI+uvahHsYIa2+nzkrpw7lhd1vx+VYsHaQInbVQX0oTbiBrb+0S6nr5weontOI66CNhz4Ru0FKPHGo8Md3mrJU/uJyEAJELghvlY9omHgn+w==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=bXOHtvNtMhHVxi9pGyN95NyCmt2c9E4rh8Hhcur3/DVhNUxTbAU84yoqgVDoGJMEqwLc57vXqU9K7PYa3k+YckdbPgsQUW46PGpNLvmFYpbD7jFz+7EMOGNPe5BUF7WxDGVfZP/A6mJS+eUdGxoqf0LAfMoW7uix341EQLLRuRV0IKyUrdiQaOhufT/3F/OGqIMIMkOIGH+M+uG9zJWEUlDuBJ1uZF0pKsST2eqh7qoy07cq+IYfyGKyCsEiCYQAdZtHa80qwGMViFndBlXxTExh5QoPiqGb90XXj9tGTNn5zHHAX/1aGzMLe8Eadwp42GVDfAM6ctbZRx8TrMvj2g==
  • Cc: <grygorii_strashko@xxxxxxxx>, <anthony.perard@xxxxxxxxxx>, <michal.orzel@xxxxxxx>, <julien@xxxxxxx>, <roger.pau@xxxxxxxxxx>, <jason.andryuk@xxxxxxx>, <victorm.lira@xxxxxxx>, <andrew.cooper3@xxxxxxxxxx>, <jbeulich@xxxxxxxx>, <sstabellini@xxxxxxxxxx>, Stefano Stabellini <stefano.stabellini@xxxxxxx>
  • Delivery-date: Wed, 04 Feb 2026 23:37:28 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Guard every mutation of serial_rx_cons/prod with console_lock so that
cross-domain reads can't see stale data:

- In console_switch_input(): protect console_rx assignment with the lock
  using irqsave/irqrestore variants since this can be called from
  interrupt context

- In __serial_rx(): protect the ring buffer write operation when
  delivering input to the hardware domain

- In do_console_io() CONSOLEIO_read: hold the lock around the entire
  read loop, using a local buffer copy to avoid holding the lock during
  copy_to_guest_offset()

This is preparatory work for allowing multiple domains to use the
console_io hypercalls where proper synchronization is required.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxx>
---
Changes in v10:
- patch split into two halves, this is the first half
---
 xen/drivers/char/console.c | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c
index fbc89ca2a4..ad53073b99 100644
--- a/xen/drivers/char/console.c
+++ b/xen/drivers/char/console.c
@@ -553,10 +553,13 @@ static void console_switch_input(void)
     {
         domid_t domid;
         struct domain *d;
+        unsigned long flags;
 
         if ( next_rx++ >= max_console_rx )
         {
+            nrspin_lock_irqsave(&console_lock, flags);
             ACCESS_ONCE(console_rx) = 0;
+            nrspin_unlock_irqrestore(&console_lock, flags);
             printk("*** Serial input to Xen");
             break;
         }
@@ -576,7 +579,9 @@ static void console_switch_input(void)
 
             rcu_unlock_domain(d);
 
+            nrspin_lock_irqsave(&console_lock, flags);
             ACCESS_ONCE(console_rx) = next_rx;
+            nrspin_unlock_irqrestore(&console_lock, flags);
             printk("*** Serial input to DOM%u", domid);
             break;
         }
@@ -602,12 +607,16 @@ static void __serial_rx(char c)
 
     if ( is_hardware_domain(d) )
     {
+        unsigned long flags;
+
         /*
          * Deliver input to the hardware domain buffer, unless it is
          * already full.
          */
+        nrspin_lock_irqsave(&console_lock, flags);
         if ( (serial_rx_prod - serial_rx_cons) != SERIAL_RX_SIZE )
             serial_rx_ring[SERIAL_RX_MASK(serial_rx_prod++)] = c;
+        nrspin_unlock_irqrestore(&console_lock, flags);
 
         /*
          * Always notify the hardware domain: prevents receive path from
@@ -796,6 +805,7 @@ long do_console_io(
 {
     long rc;
     unsigned int idx, len;
+    char kbuf[SERIAL_RX_SIZE];
 
     rc = xsm_console_io(XSM_OTHER, current->domain, cmd);
     if ( rc )
@@ -817,6 +827,7 @@ long do_console_io(
             break;
 
         rc = 0;
+        nrspin_lock_irq(&console_lock);
         while ( (serial_rx_cons != serial_rx_prod) && (rc < count) )
         {
             idx = SERIAL_RX_MASK(serial_rx_cons);
@@ -825,14 +836,19 @@ long do_console_io(
                 len = SERIAL_RX_SIZE - idx;
             if ( (rc + len) > count )
                 len = count - rc;
-            if ( copy_to_guest_offset(buffer, rc, &serial_rx_ring[idx], len) )
-            {
-                rc = -EFAULT;
-                break;
-            }
+            memcpy(kbuf, &serial_rx_ring[idx], len);
+
+            nrspin_unlock_irq(&console_lock);
+
+            if ( copy_to_guest_offset(buffer, rc, kbuf, len) )
+               return -EFAULT;
             rc += len;
+
+            nrspin_lock_irq(&console_lock);
+
             serial_rx_cons += len;
         }
+        nrspin_unlock_irq(&console_lock);
         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®.