ia64/xen-unstable

changeset 5327:84ce09862452

bitkeeper revision 1.1676 (42a306a07UKpLq27_iCaJyxJBbKedg)

More console cleanups. The console ring now overwrites its tail when
it fills, rather than stop recording output. The guest serial output
is only allowed to half-fill the serial output buffer, and now
respects hypercall preemption requests.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Sun Jun 05 14:05:20 2005 +0000 (2005-06-05)
parents fd6da43c07ab
children 0fd1b16571fb
files tools/libxc/xc.h tools/libxc/xc_misc.c tools/python/xen/lowlevel/xc/xc.c xen/common/dom0_ops.c xen/common/domain.c xen/drivers/char/console.c xen/drivers/char/serial.c xen/include/public/dom0_ops.h xen/include/xen/console.h xen/include/xen/serial.h
line diff
     1.1 --- a/tools/libxc/xc.h	Sun Jun 05 10:53:57 2005 +0000
     1.2 +++ b/tools/libxc/xc.h	Sun Jun 05 14:05:20 2005 +0000
     1.3 @@ -388,8 +388,8 @@ int xc_physdev_pci_access_modify(int xc_
     1.4                                   int enable);
     1.5  
     1.6  int xc_readconsolering(int xc_handle,
     1.7 -                       char *str, 
     1.8 -                       unsigned int max_chars, 
     1.9 +                       char **pbuffer,
    1.10 +                       unsigned int *pnr_chars, 
    1.11                         int clear);
    1.12  
    1.13  typedef dom0_physinfo_t xc_physinfo_t;
     2.1 --- a/tools/libxc/xc_misc.c	Sun Jun 05 10:53:57 2005 +0000
     2.2 +++ b/tools/libxc/xc_misc.c	Sun Jun 05 14:05:20 2005 +0000
     2.3 @@ -19,34 +19,35 @@ int xc_interface_close(int xc_handle)
     2.4      return close(xc_handle);
     2.5  }
     2.6  
     2.7 -
     2.8 -#define CONSOLE_RING_CLEAR 1
     2.9 -
    2.10  int xc_readconsolering(int xc_handle,
    2.11 -                       char *str, 
    2.12 -                       unsigned int max_chars, 
    2.13 +                       char **pbuffer,
    2.14 +                       unsigned int *pnr_chars, 
    2.15                         int clear)
    2.16  {
    2.17      int ret;
    2.18      dom0_op_t op;
    2.19 +    char *buffer = *pbuffer;
    2.20 +    unsigned int nr_chars = *pnr_chars;
    2.21  
    2.22      op.cmd = DOM0_READCONSOLE;
    2.23 -    op.u.readconsole.str = (unsigned long)str;
    2.24 -    op.u.readconsole.count = max_chars;
    2.25 -    op.u.readconsole.cmd = clear ? CONSOLE_RING_CLEAR : 0;
    2.26 +    op.u.readconsole.buffer = buffer;
    2.27 +    op.u.readconsole.count  = nr_chars;
    2.28 +    op.u.readconsole.clear  = clear;
    2.29  
    2.30 -    if ( (ret = mlock(str, max_chars)) != 0 )
    2.31 +    if ( (ret = mlock(buffer, nr_chars)) != 0 )
    2.32          return ret;
    2.33  
    2.34 -    if ( (ret = do_dom0_op(xc_handle, &op)) >= 0 )
    2.35 -        str[ret] = '\0';
    2.36 +    if ( (ret = do_dom0_op(xc_handle, &op)) == 0 )
    2.37 +    {
    2.38 +        *pbuffer   = op.u.readconsole.buffer;
    2.39 +        *pnr_chars = op.u.readconsole.count;
    2.40 +    }
    2.41  
    2.42 -    (void)munlock(str, max_chars);
    2.43 +    (void)munlock(buffer, nr_chars);
    2.44  
    2.45      return ret;
    2.46  }    
    2.47  
    2.48 -
    2.49  int xc_physinfo(int xc_handle,
    2.50                  xc_physinfo_t *put_info)
    2.51  {
    2.52 @@ -64,7 +65,6 @@ int xc_physinfo(int xc_handle,
    2.53      return 0;
    2.54  }
    2.55  
    2.56 -
    2.57  int xc_sched_id(int xc_handle,
    2.58                  int *sched_id)
    2.59  {
     3.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Sun Jun 05 10:53:57 2005 +0000
     3.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Sun Jun 05 14:05:20 2005 +0000
     3.3 @@ -678,7 +678,8 @@ static PyObject *pyxc_readconsolering(Py
     3.4      XcObject *xc = (XcObject *)self;
     3.5  
     3.6      unsigned int clear = 0;
     3.7 -    char         str[32768];
     3.8 +    char         _str[32768], *str = _str;
     3.9 +    unsigned int count = 32768;
    3.10      int          ret;
    3.11  
    3.12      static char *kwd_list[] = { "clear", NULL };
    3.13 @@ -686,11 +687,11 @@ static PyObject *pyxc_readconsolering(Py
    3.14      if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwd_list, &clear) )
    3.15          return NULL;
    3.16  
    3.17 -    ret = xc_readconsolering(xc->xc_handle, str, sizeof(str), clear);
    3.18 +    ret = xc_readconsolering(xc->xc_handle, &str, &count, clear);
    3.19      if ( ret < 0 )
    3.20          return PyErr_SetFromErrno(xc_error);
    3.21  
    3.22 -    return PyString_FromStringAndSize(str, ret);
    3.23 +    return PyString_FromStringAndSize(str, count);
    3.24  }
    3.25  
    3.26  static PyObject *pyxc_physinfo(PyObject *self,
     4.1 --- a/xen/common/dom0_ops.c	Sun Jun 05 10:53:57 2005 +0000
     4.2 +++ b/xen/common/dom0_ops.c	Sun Jun 05 14:05:20 2005 +0000
     4.3 @@ -449,9 +449,11 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
     4.4      
     4.5      case DOM0_READCONSOLE:
     4.6      {
     4.7 -        ret = read_console_ring(op->u.readconsole.str, 
     4.8 -                                op->u.readconsole.count,
     4.9 -                                op->u.readconsole.cmd); 
    4.10 +        ret = read_console_ring(
    4.11 +            &op->u.readconsole.buffer, 
    4.12 +            &op->u.readconsole.count,
    4.13 +            op->u.readconsole.clear); 
    4.14 +        copy_to_user(u_dom0_op, op, sizeof(*op));
    4.15      }
    4.16      break;
    4.17  
     5.1 --- a/xen/common/domain.c	Sun Jun 05 10:53:57 2005 +0000
     5.2 +++ b/xen/common/domain.c	Sun Jun 05 14:05:20 2005 +0000
     5.3 @@ -122,18 +122,9 @@ void domain_kill(struct domain *d)
     5.4  
     5.5  void domain_crash(void)
     5.6  {
     5.7 -    struct domain *d = current->domain;
     5.8 -
     5.9 -    if ( d->domain_id == 0 )
    5.10 -    {
    5.11 -        show_registers(guest_cpu_user_regs());
    5.12 -        panic("Domain 0 crashed!\n");
    5.13 -    }
    5.14 -
    5.15 -#ifndef NDEBUG
    5.16 +    printk("Domain %d (vcpu#%d) crashed on cpu#%d:\n",
    5.17 +           current->domain->domain_id, current->vcpu_id, smp_processor_id());
    5.18      show_registers(guest_cpu_user_regs());
    5.19 -#endif
    5.20 -
    5.21      domain_shutdown(SHUTDOWN_crash);
    5.22  }
    5.23  
     6.1 --- a/xen/drivers/char/console.c	Sun Jun 05 10:53:57 2005 +0000
     6.2 +++ b/xen/drivers/char/console.c	Sun Jun 05 14:05:20 2005 +0000
     6.3 @@ -16,6 +16,7 @@
     6.4  #include <xen/spinlock.h>
     6.5  #include <xen/console.h>
     6.6  #include <xen/serial.h>
     6.7 +#include <xen/softirq.h>
     6.8  #include <xen/keyhandler.h>
     6.9  #include <xen/mm.h>
    6.10  #include <xen/delay.h>
    6.11 @@ -42,13 +43,10 @@ boolean_param("sync_console", opt_sync_c
    6.12  static int xpos, ypos;
    6.13  static unsigned char *video;
    6.14  
    6.15 -#define CONSOLE_RING_SIZE 16392
    6.16 -typedef struct console_ring_st
    6.17 -{
    6.18 -    char buf[CONSOLE_RING_SIZE];
    6.19 -    unsigned int len;
    6.20 -} console_ring_t;
    6.21 -static console_ring_t console_ring;
    6.22 +#define CONRING_SIZE 16384
    6.23 +#define CONRING_IDX_MASK(i) ((i)&(CONRING_SIZE-1))
    6.24 +static char conring[CONRING_SIZE];
    6.25 +static unsigned int conringc, conringp;
    6.26  
    6.27  static char printk_prefix[16] = "";
    6.28  
    6.29 @@ -218,23 +216,33 @@ static void putchar_console(int c)
    6.30  
    6.31  static void putchar_console_ring(int c)
    6.32  {
    6.33 -    if ( console_ring.len < CONSOLE_RING_SIZE )
    6.34 -        console_ring.buf[console_ring.len++] = (char)c;
    6.35 +    conring[CONRING_IDX_MASK(conringp++)] = c;
    6.36 +    if ( (conringp - conringc) > CONRING_SIZE )
    6.37 +        conringc = conringp - CONRING_SIZE;
    6.38  }
    6.39  
    6.40 -long read_console_ring(unsigned long str, unsigned int count, unsigned cmd)
    6.41 +long read_console_ring(char **pstr, u32 *pcount, int clear)
    6.42  {
    6.43 -    unsigned int len;
    6.44 -    
    6.45 -    len = (console_ring.len < count) ? console_ring.len : count;
    6.46 -    
    6.47 -    if ( copy_to_user((char *)str, console_ring.buf, len) )
    6.48 -        return -EFAULT;
    6.49 +    char *str = *pstr;
    6.50 +    u32 count = *pcount;
    6.51 +    unsigned int p, q;
    6.52 +    unsigned long flags;
    6.53 +
    6.54 +    /* Start of buffer may get overwritten during copy. So copy backwards. */
    6.55 +    for ( p = conringp, q = count; (p > conringc) && (q > 0); p--, q-- )
    6.56 +        if ( put_user(conring[CONRING_IDX_MASK(p-1)], (char *)str+q-1) )
    6.57 +            return -EFAULT;
    6.58  
    6.59 -    if ( cmd & CONSOLE_RING_CLEAR )
    6.60 -        console_ring.len = 0;
    6.61 -    
    6.62 -    return len;
    6.63 +    if ( clear )
    6.64 +    {
    6.65 +        spin_lock_irqsave(&console_lock, flags);
    6.66 +        conringc = conringp;
    6.67 +        spin_unlock_irqrestore(&console_lock, flags);
    6.68 +    }
    6.69 +
    6.70 +    *pstr   = str + q;
    6.71 +    *pcount = count - q;
    6.72 +    return 0;
    6.73  }
    6.74  
    6.75  
    6.76 @@ -301,13 +309,44 @@ static void serial_rx(char c, struct cpu
    6.77      __serial_rx(c, regs);
    6.78  }
    6.79  
    6.80 +long guest_console_write(char *buffer, int count)
    6.81 +{
    6.82 +    char kbuf[128];
    6.83 +    int kcount;
    6.84 +
    6.85 +    while ( count > 0 )
    6.86 +    {
    6.87 +        while ( serial_tx_space(sercon_handle) < (SERIAL_TXBUFSZ / 2) )
    6.88 +        {
    6.89 +            if ( hypercall_preempt_check() )
    6.90 +                break;
    6.91 +            cpu_relax();
    6.92 +        }
    6.93 +
    6.94 +        if ( hypercall_preempt_check() )
    6.95 +            return hypercall3_create_continuation(
    6.96 +                __HYPERVISOR_console_io, CONSOLEIO_write, count, buffer);
    6.97 +
    6.98 +        kcount = min_t(int, count, sizeof(kbuf)-1);
    6.99 +        if ( copy_from_user(kbuf, buffer, kcount) )
   6.100 +            return -EFAULT;
   6.101 +        kbuf[kcount] = '\0';
   6.102 +
   6.103 +        serial_puts(sercon_handle, kbuf);
   6.104 +
   6.105 +        buffer += kcount;
   6.106 +        count  -= kcount;
   6.107 +    }
   6.108 +
   6.109 +    return 0;
   6.110 +}
   6.111 +
   6.112  long do_console_io(int cmd, int count, char *buffer)
   6.113  {
   6.114 -    char *kbuf;
   6.115 -    long  rc;
   6.116 +    long rc;
   6.117  
   6.118  #ifndef VERBOSE
   6.119 -    /* Only domain-0 may access the emergency console. */
   6.120 +    /* Only domain 0 may access the emergency console. */
   6.121      if ( current->domain->domain_id != 0 )
   6.122          return -EPERM;
   6.123  #endif
   6.124 @@ -315,17 +354,7 @@ long do_console_io(int cmd, int count, c
   6.125      switch ( cmd )
   6.126      {
   6.127      case CONSOLEIO_write:
   6.128 -        if ( count > (PAGE_SIZE-1) )
   6.129 -            count = PAGE_SIZE-1;
   6.130 -        if ( (kbuf = (char *)alloc_xenheap_page()) == NULL )
   6.131 -            return -ENOMEM;
   6.132 -        kbuf[count] = '\0';
   6.133 -        rc = count;
   6.134 -        if ( copy_from_user(kbuf, buffer, count) )
   6.135 -            rc = -EFAULT;
   6.136 -        else
   6.137 -            serial_puts(sercon_handle, kbuf);
   6.138 -        free_xenheap_page((unsigned long)kbuf);
   6.139 +        rc = guest_console_write(buffer, count);
   6.140          break;
   6.141      case CONSOLEIO_read:
   6.142          rc = 0;
     7.1 --- a/xen/drivers/char/serial.c	Sun Jun 05 10:53:57 2005 +0000
     7.2 +++ b/xen/drivers/char/serial.c	Sun Jun 05 14:05:20 2005 +0000
     7.3 @@ -317,6 +317,14 @@ void serial_end_sync(int handle)
     7.4      spin_unlock_irqrestore(&port->lock, flags);
     7.5  }
     7.6  
     7.7 +int serial_tx_space(int handle)
     7.8 +{
     7.9 +    struct serial_port *port = &com[handle & SERHND_IDX];
    7.10 +    if ( handle == -1 )
    7.11 +        return SERIAL_TXBUFSZ;
    7.12 +    return SERIAL_TXBUFSZ - (port->txbufp - port->txbufc);
    7.13 +}
    7.14 +
    7.15  void serial_init_preirq(void)
    7.16  {
    7.17      int i;
     8.1 --- a/xen/include/public/dom0_ops.h	Sun Jun 05 10:53:57 2005 +0000
     8.2 +++ b/xen/include/public/dom0_ops.h	Sun Jun 05 14:05:20 2005 +0000
     8.3 @@ -164,9 +164,11 @@ typedef struct {
     8.4   */
     8.5  #define DOM0_READCONSOLE      19
     8.6  typedef struct {
     8.7 -    memory_t str;
     8.8 -    u32      count;
     8.9 -    u32      cmd;
    8.10 +    /* IN variables. */
    8.11 +    u32      clear;        /* Non-zero -> clear after reading. */
    8.12 +    /* IN/OUT variables. */
    8.13 +    char    *buffer;       /* In: Buffer start; Out: Used buffer start */
    8.14 +    u32      count;        /* In: Buffer size;  Out: Used buffer size  */
    8.15  } dom0_readconsole_t;
    8.16  
    8.17  /* 
     9.1 --- a/xen/include/xen/console.h	Sun Jun 05 10:53:57 2005 +0000
     9.2 +++ b/xen/include/xen/console.h	Sun Jun 05 14:05:20 2005 +0000
     9.3 @@ -13,8 +13,7 @@ extern spinlock_t console_lock;
     9.4  
     9.5  void set_printk_prefix(const char *prefix);
     9.6  
     9.7 -#define CONSOLE_RING_CLEAR 1
     9.8 -long read_console_ring(unsigned long, unsigned int, unsigned int);
     9.9 +long read_console_ring(char **, u32 *, int);
    9.10  
    9.11  void init_console(void);
    9.12  void console_endboot(int disable_vga);
    10.1 --- a/xen/include/xen/serial.h	Sun Jun 05 10:53:57 2005 +0000
    10.2 +++ b/xen/include/xen/serial.h	Sun Jun 05 14:05:20 2005 +0000
    10.3 @@ -96,6 +96,9 @@ void serial_force_unlock(int handle);
    10.4  void serial_start_sync(int handle);
    10.5  void serial_end_sync(int handle);
    10.6  
    10.7 +/* Return number of bytes headroom in transmit buffer. */
    10.8 +int serial_tx_space(int handle);
    10.9 +
   10.10  /*
   10.11   * Initialisation and helper functions for uart drivers.
   10.12   */