xen/console: introduce console_{get,put}_domain()

console_input_domain() takes an RCU lock to protect domain structure.
That implies call to rcu_unlock_domain() after use.

Introduce a pair of console_get_domain() / console_put_domain() to highlight
the correct use of the call within the code interacting with Xen console
driver.

The new calls used in __serial_rx(), which also fixed console forwarding to
late hardware domains which run with domain IDs different from 0.

While moving the guest_printk() invocation also drop the redundant _G infix.

Signed-off-by: Denis Mukhin <dmukhin@ford.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
This commit is contained in:
Denis Mukhin authored and Jan Beulich committed 2025-03-05 15:42:49 +01:00
1 parent 86e14fe17f
commit 91db39013a
3 files changed
+33 -30

No files matched your search

+3 -3
View File
@@ -78,7 +78,7 @@ static void vpl011_write_data_xen(struct domain *d, uint8_t data)
unsigned long flags;
struct vpl011 *vpl011 = &d->arch.vpl011;
struct vpl011_xen_backend *intf = vpl011->backend.xen;
struct domain *input = console_input_domain();
struct domain *input = console_get_domain();
VPL011_LOCK(d, flags);
@@ -123,8 +123,8 @@ static void vpl011_write_data_xen(struct domain *d, uint8_t data)
vpl011_update_interrupt_status(d);
VPL011_UNLOCK(d, flags);
if ( input != NULL )
rcu_unlock_domain(input);
console_put_domain(input);
}
/*
+28 -26
View File
@@ -474,15 +474,18 @@ static unsigned int __read_mostly console_rx = 0;
#define max_console_rx (max_init_domid + 1)
#ifdef CONFIG_SBSA_VUART_CONSOLE
/* Make sure to rcu_unlock_domain after use */
struct domain *console_input_domain(void)
struct domain *console_get_domain(void)
{
if ( console_rx == 0 )
return NULL;
return rcu_lock_domain_by_id(console_rx - 1);
}
#endif
void console_put_domain(struct domain *d)
{
if ( d )
rcu_unlock_domain(d);
}
static void switch_serial_input(void)
{
@@ -528,12 +531,18 @@ static void switch_serial_input(void)
static void __serial_rx(char c)
{
switch ( console_rx )
{
case 0:
struct domain *d;
int rc = 0;
if ( console_rx == 0 )
return handle_keypress(c, false);
case 1:
d = console_get_domain();
if ( !d )
return;
if ( is_hardware_domain(d) )
{
/*
* Deliver input to the hardware domain buffer, unless it is
* already full.
@@ -546,31 +555,24 @@ static void __serial_rx(char c)
* getting stuck.
*/
send_global_virq(VIRQ_CONSOLE);
break;
}
#ifdef CONFIG_SBSA_VUART_CONSOLE
default:
{
struct domain *d = rcu_lock_domain_by_id(console_rx - 1);
if ( d )
{
int rc = vpl011_rx_char_xen(d, c);
if ( rc )
guest_printk(d, XENLOG_G_WARNING
"failed to process console input: %d\n", rc);
rcu_unlock_domain(d);
}
break;
}
else
/* Deliver input to the emulated UART. */
rc = vpl011_rx_char_xen(d, c);
#endif
}
if ( rc )
guest_printk(d,
XENLOG_WARNING "failed to process console input: %d\n",
rc);
#ifdef CONFIG_X86
if ( pv_shim && pv_console )
consoled_guest_tx(c);
#endif
console_put_domain(d);
}
static void cf_check serial_rx(char c)
+2 -1
View File
@@ -32,7 +32,8 @@ void console_end_sync(void);
void console_start_log_everything(void);
void console_end_log_everything(void);
struct domain *console_input_domain(void);
struct domain *console_get_domain(void);
void console_put_domain(struct domain *d);
/*
* Steal output from the console. Returns +ve identifier, else -ve error.
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.