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

Re: [PATCH v8 1/2] xen/console: handle multiple domains using console_io hypercalls


  • To: Stefano Stabellini <stefano.stabellini@xxxxxxx>
  • From: Jan Beulich <jbeulich@xxxxxxxx>
  • Date: Tue, 3 Feb 2026 16:30:40 +0100
  • Autocrypt: addr=jbeulich@xxxxxxxx; keydata= xsDiBFk3nEQRBADAEaSw6zC/EJkiwGPXbWtPxl2xCdSoeepS07jW8UgcHNurfHvUzogEq5xk hu507c3BarVjyWCJOylMNR98Yd8VqD9UfmX0Hb8/BrA+Hl6/DB/eqGptrf4BSRwcZQM32aZK 7Pj2XbGWIUrZrd70x1eAP9QE3P79Y2oLrsCgbZJfEwCgvz9JjGmQqQkRiTVzlZVCJYcyGGsD /0tbFCzD2h20ahe8rC1gbb3K3qk+LpBtvjBu1RY9drYk0NymiGbJWZgab6t1jM7sk2vuf0Py O9Hf9XBmK0uE9IgMaiCpc32XV9oASz6UJebwkX+zF2jG5I1BfnO9g7KlotcA/v5ClMjgo6Gl MDY4HxoSRu3i1cqqSDtVlt+AOVBJBACrZcnHAUSuCXBPy0jOlBhxPqRWv6ND4c9PH1xjQ3NP nxJuMBS8rnNg22uyfAgmBKNLpLgAGVRMZGaGoJObGf72s6TeIqKJo/LtggAS9qAUiuKVnygo 3wjfkS9A3DRO+SpU7JqWdsveeIQyeyEJ/8PTowmSQLakF+3fote9ybzd880fSmFuIEJldWxp Y2ggPGpiZXVsaWNoQHN1c2UuY29tPsJgBBMRAgAgBQJZN5xEAhsDBgsJCAcDAgQVAggDBBYC AwECHgECF4AACgkQoDSui/t3IH4J+wCfQ5jHdEjCRHj23O/5ttg9r9OIruwAn3103WUITZee e7Sbg12UgcQ5lv7SzsFNBFk3nEQQCACCuTjCjFOUdi5Nm244F+78kLghRcin/awv+IrTcIWF hUpSs1Y91iQQ7KItirz5uwCPlwejSJDQJLIS+QtJHaXDXeV6NI0Uef1hP20+y8qydDiVkv6l IreXjTb7DvksRgJNvCkWtYnlS3mYvQ9NzS9PhyALWbXnH6sIJd2O9lKS1Mrfq+y0IXCP10eS FFGg+Av3IQeFatkJAyju0PPthyTqxSI4lZYuJVPknzgaeuJv/2NccrPvmeDg6Coe7ZIeQ8Yj t0ARxu2xytAkkLCel1Lz1WLmwLstV30g80nkgZf/wr+/BXJW/oIvRlonUkxv+IbBM3dX2OV8 AmRv1ySWPTP7AAMFB/9PQK/VtlNUJvg8GXj9ootzrteGfVZVVT4XBJkfwBcpC/XcPzldjv+3 HYudvpdNK3lLujXeA5fLOH+Z/G9WBc5pFVSMocI71I8bT8lIAzreg0WvkWg5V2WZsUMlnDL9 mpwIGFhlbM3gfDMs7MPMu8YQRFVdUvtSpaAs8OFfGQ0ia3LGZcjA6Ik2+xcqscEJzNH+qh8V m5jjp28yZgaqTaRbg3M/+MTbMpicpZuqF4rnB0AQD12/3BNWDR6bmh+EkYSMcEIpQmBM51qM EKYTQGybRCjpnKHGOxG0rfFY1085mBDZCH5Kx0cl0HVJuQKC+dV2ZY5AqjcKwAxpE75MLFkr wkkEGBECAAkFAlk3nEQCGwwACgkQoDSui/t3IH7nnwCfcJWUDUFKdCsBH/E5d+0ZnMQi+G0A nAuWpQkjM1ASeQwSHEeAWPgskBQL
  • Cc: grygorii_strashko@xxxxxxxx, anthony.perard@xxxxxxxxxx, michal.orzel@xxxxxxx, julien@xxxxxxx, roger.pau@xxxxxxxxxx, jason.andryuk@xxxxxxx, victorm.lira@xxxxxxx, andrew.cooper3@xxxxxxxxxx, sstabellini@xxxxxxxxxx, xen-devel@xxxxxxxxxxxxxxxxxxxx
  • Delivery-date: Tue, 03 Feb 2026 15:31:08 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On 29.01.2026 23:08, Stefano Stabellini wrote:
> --- a/xen/drivers/char/console.c
> +++ b/xen/drivers/char/console.c
> @@ -518,11 +518,16 @@ static unsigned int __read_mostly console_rx = 0;
>  struct domain *console_get_domain(void)
>  {
>      struct domain *d;
> +    unsigned int rx;
>  
> -    if ( console_rx == 0 )
> +    nrspin_lock(&console_lock);
> +    rx = console_rx;
> +    nrspin_unlock(&console_lock);

Did you test this in a debug build, and it didn't blow up? The console lock
is an IRQ-safe one, so I'd expect check_lock() to complain that you do not
disable IRQs here. At the same time I don't think you can rely on IRQs being
off upon entry into the function.

Anyway - is locking here really needed? Wouldn't suitable use of ACCESS_ONCE()
(also elsewhere) do? (Such a switchover likely could be a separate, prereq
patch.)

Further, if already you add locking on the read sides, what about ...

> @@ -540,6 +545,12 @@ void console_put_domain(struct domain *d)
>          rcu_unlock_domain(d);
>  }
>  
> +static bool is_focus_domain(const struct domain *d)
> +{
> +    ASSERT(rspin_is_locked(&console_lock));
> +    return d != NULL && d->domain_id == console_rx - 1;
> +}
> +
>  static void console_switch_input(void)
>  {
>      unsigned int next_rx = console_rx;

... this read?

> @@ -555,7 +566,10 @@ static void console_switch_input(void)
>  
>          if ( next_rx++ >= max_console_rx )
>          {
> +            nrspin_lock_irq(&console_lock);

As indicated earlier, you can't know IRQ state in anything down the call
tree from serial_rx().

> @@ -742,17 +765,36 @@ 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) )
> +        /*
> +         * Take both cons->lock and console_lock:
> +         * - cons->lock protects cons->buf and cons->idx
> +         * - console_lock protects console_send() and is_focus_domain()
> +         *   checks
> +         *
> +         * The order must be respected. guest_printk() takes the
> +         * console_lock so it is important that cons->lock is taken
> +         * first.
> +         */
> +        spin_lock(&cons->lock);
> +        nrspin_lock_irq(&console_lock);

While guest_printk() does matter here, it taking (down the call tree)
console_lock isn't alone relevant. It being called with cons->lock held
is, .

> @@ -816,22 +857,39 @@ long do_console_io(
>              break;
>  
>          rc = 0;
> +        nrspin_lock_irq(&console_lock);
> +        if ( !is_focus_domain(current->domain) )
> +            count = 0;
>          while ( (serial_rx_cons != serial_rx_prod) && (rc < count) )
>          {
>              idx = SERIAL_RX_MASK(serial_rx_cons);
>              len = serial_rx_prod - serial_rx_cons;
> +            nrspin_unlock_irq(&console_lock);

Can we please have blank lines on both sides of this?

>              if ( (idx + len) > SERIAL_RX_SIZE )
>                  len = SERIAL_RX_SIZE - idx;
>              if ( (rc + len) > count )
>                  len = count - rc;
>              if ( copy_to_guest_offset(buffer, rc, &serial_rx_ring[idx], len) 
> )

Have I perhaps talked you into moving the unlock too early? serial_rx_ring[]
accesses look like they need to be with the lock still held. Or, to avoid
calling copy_to_guest_offset() with the lock held, a local copy would need
making.

Jan



 


Rackspace

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