|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v2] 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>
---
Changes in v2:
- fix code style
- pbuf_idx/idx after ada53067083e
- don't add extra \0
- clear input on console switch
---
xen/drivers/char/console.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c
index 2bdb4d5fb4..6c7a6592c5 100644
--- a/xen/drivers/char/console.c
+++ b/xen/drivers/char/console.c
@@ -576,6 +576,8 @@ static void console_switch_input(void)
rcu_unlock_domain(d);
console_rx = next_rx;
+ /* don't let the next dom read the previous dom's unread data */
+ serial_rx_cons = serial_rx_prod;
printk("*** Serial input to DOM%u", domid);
break;
}
@@ -730,6 +732,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 )
{
@@ -742,18 +745,28 @@ 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 )
{
+ struct domain_console *cons = cd->console;
+
+ if ( cons->idx )
+ {
+ console_send(cons->buf, cons->idx, flags);
+ cons->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;
struct domain_console *cons = cd->console;
+ console_put_domain(input);
/* Strip non-printable characters */
do
{
@@ -795,6 +808,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 )
@@ -815,6 +829,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) )
{
@@ -826,12 +847,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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |