ChangeSet 1.1676, 2005/06/05 15:05:20+01:00, kaf24@xxxxxxxxxxxxxxxxxxxx
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@xxxxxxxxxxxxx>
tools/libxc/xc.h | 4 -
tools/libxc/xc_misc.c | 28 +++++-----
tools/python/xen/lowlevel/xc/xc.c | 7 +-
xen/common/dom0_ops.c | 8 +--
xen/common/domain.c | 13 -----
xen/drivers/char/console.c | 97 ++++++++++++++++++++++++--------------
xen/drivers/char/serial.c | 8 +++
xen/include/public/dom0_ops.h | 8 +--
xen/include/xen/console.h | 3 -
xen/include/xen/serial.h | 3 +
10 files changed, 107 insertions(+), 72 deletions(-)
diff -Nru a/tools/libxc/xc.h b/tools/libxc/xc.h
--- a/tools/libxc/xc.h 2005-06-05 11:02:47 -04:00
+++ b/tools/libxc/xc.h 2005-06-05 11:02:47 -04:00
@@ -388,8 +388,8 @@
int enable);
int xc_readconsolering(int xc_handle,
- char *str,
- unsigned int max_chars,
+ char **pbuffer,
+ unsigned int *pnr_chars,
int clear);
typedef dom0_physinfo_t xc_physinfo_t;
diff -Nru a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c
--- a/tools/libxc/xc_misc.c 2005-06-05 11:02:47 -04:00
+++ b/tools/libxc/xc_misc.c 2005-06-05 11:02:47 -04:00
@@ -19,34 +19,35 @@
return close(xc_handle);
}
-
-#define CONSOLE_RING_CLEAR 1
-
int xc_readconsolering(int xc_handle,
- char *str,
- unsigned int max_chars,
+ char **pbuffer,
+ unsigned int *pnr_chars,
int clear)
{
int ret;
dom0_op_t op;
+ char *buffer = *pbuffer;
+ unsigned int nr_chars = *pnr_chars;
op.cmd = DOM0_READCONSOLE;
- op.u.readconsole.str = (unsigned long)str;
- op.u.readconsole.count = max_chars;
- op.u.readconsole.cmd = clear ? CONSOLE_RING_CLEAR : 0;
+ op.u.readconsole.buffer = buffer;
+ op.u.readconsole.count = nr_chars;
+ op.u.readconsole.clear = clear;
- if ( (ret = mlock(str, max_chars)) != 0 )
+ if ( (ret = mlock(buffer, nr_chars)) != 0 )
return ret;
- if ( (ret = do_dom0_op(xc_handle, &op)) >= 0 )
- str[ret] = '\0';
+ if ( (ret = do_dom0_op(xc_handle, &op)) == 0 )
+ {
+ *pbuffer = op.u.readconsole.buffer;
+ *pnr_chars = op.u.readconsole.count;
+ }
- (void)munlock(str, max_chars);
+ (void)munlock(buffer, nr_chars);
return ret;
}
-
int xc_physinfo(int xc_handle,
xc_physinfo_t *put_info)
{
@@ -63,7 +64,6 @@
return 0;
}
-
int xc_sched_id(int xc_handle,
int *sched_id)
diff -Nru a/tools/python/xen/lowlevel/xc/xc.c
b/tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c 2005-06-05 11:02:48 -04:00
+++ b/tools/python/xen/lowlevel/xc/xc.c 2005-06-05 11:02:48 -04:00
@@ -678,7 +678,8 @@
XcObject *xc = (XcObject *)self;
unsigned int clear = 0;
- char str[32768];
+ char _str[32768], *str = _str;
+ unsigned int count = 32768;
int ret;
static char *kwd_list[] = { "clear", NULL };
@@ -686,11 +687,11 @@
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|i", kwd_list, &clear) )
return NULL;
- ret = xc_readconsolering(xc->xc_handle, str, sizeof(str), clear);
+ ret = xc_readconsolering(xc->xc_handle, &str, &count, clear);
if ( ret < 0 )
return PyErr_SetFromErrno(xc_error);
- return PyString_FromStringAndSize(str, ret);
+ return PyString_FromStringAndSize(str, count);
}
static PyObject *pyxc_physinfo(PyObject *self,
diff -Nru a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c
--- a/xen/common/dom0_ops.c 2005-06-05 11:02:47 -04:00
+++ b/xen/common/dom0_ops.c 2005-06-05 11:02:47 -04:00
@@ -449,9 +449,11 @@
case DOM0_READCONSOLE:
{
- ret = read_console_ring(op->u.readconsole.str,
- op->u.readconsole.count,
- op->u.readconsole.cmd);
+ ret = read_console_ring(
+ &op->u.readconsole.buffer,
+ &op->u.readconsole.count,
+ op->u.readconsole.clear);
+ copy_to_user(u_dom0_op, op, sizeof(*op));
}
break;
diff -Nru a/xen/common/domain.c b/xen/common/domain.c
--- a/xen/common/domain.c 2005-06-05 11:02:47 -04:00
+++ b/xen/common/domain.c 2005-06-05 11:02:47 -04:00
@@ -122,18 +122,9 @@
void domain_crash(void)
{
- struct domain *d = current->domain;
-
- if ( d->domain_id == 0 )
- {
- show_registers(guest_cpu_user_regs());
- panic("Domain 0 crashed!\n");
- }
-
-#ifndef NDEBUG
+ printk("Domain %d (vcpu#%d) crashed on cpu#%d:\n",
+ current->domain->domain_id, current->vcpu_id, smp_processor_id());
show_registers(guest_cpu_user_regs());
-#endif
-
domain_shutdown(SHUTDOWN_crash);
}
diff -Nru a/xen/drivers/char/console.c b/xen/drivers/char/console.c
--- a/xen/drivers/char/console.c 2005-06-05 11:02:47 -04:00
+++ b/xen/drivers/char/console.c 2005-06-05 11:02:47 -04:00
@@ -16,6 +16,7 @@
#include <xen/spinlock.h>
#include <xen/console.h>
#include <xen/serial.h>
+#include <xen/softirq.h>
#include <xen/keyhandler.h>
#include <xen/mm.h>
#include <xen/delay.h>
@@ -42,13 +43,10 @@
static int xpos, ypos;
static unsigned char *video;
-#define CONSOLE_RING_SIZE 16392
-typedef struct console_ring_st
-{
- char buf[CONSOLE_RING_SIZE];
- unsigned int len;
-} console_ring_t;
-static console_ring_t console_ring;
+#define CONRING_SIZE 16384
+#define CONRING_IDX_MASK(i) ((i)&(CONRING_SIZE-1))
+static char conring[CONRING_SIZE];
+static unsigned int conringc, conringp;
static char printk_prefix[16] = "";
@@ -218,23 +216,33 @@
static void putchar_console_ring(int c)
{
- if ( console_ring.len < CONSOLE_RING_SIZE )
- console_ring.buf[console_ring.len++] = (char)c;
+ conring[CONRING_IDX_MASK(conringp++)] = c;
+ if ( (conringp - conringc) > CONRING_SIZE )
+ conringc = conringp - CONRING_SIZE;
}
-long read_console_ring(unsigned long str, unsigned int count, unsigned cmd)
+long read_console_ring(char **pstr, u32 *pcount, int clear)
{
- unsigned int len;
-
- len = (console_ring.len < count) ? console_ring.len : count;
-
- if ( copy_to_user((char *)str, console_ring.buf, len) )
- return -EFAULT;
+ char *str = *pstr;
+ u32 count = *pcount;
+ unsigned int p, q;
+ unsigned long flags;
- if ( cmd & CONSOLE_RING_CLEAR )
- console_ring.len = 0;
-
- return len;
+ /* Start of buffer may get overwritten during copy. So copy backwards. */
+ for ( p = conringp, q = count; (p > conringc) && (q > 0); p--, q-- )
+ if ( put_user(conring[CONRING_IDX_MASK(p-1)], (char *)str+q-1) )
+ return -EFAULT;
+
+ if ( clear )
+ {
+ spin_lock_irqsave(&console_lock, flags);
+ conringc = conringp;
+ spin_unlock_irqrestore(&console_lock, flags);
+ }
+
+ *pstr = str + q;
+ *pcount = count - q;
+ return 0;
}
@@ -301,13 +309,44 @@
__serial_rx(c, regs);
}
+long guest_console_write(char *buffer, int count)
+{
+ char kbuf[128];
+ int kcount;
+
+ while ( count > 0 )
+ {
+ while ( serial_tx_space(sercon_handle) < (SERIAL_TXBUFSZ / 2) )
+ {
+ if ( hypercall_preempt_check() )
+ break;
+ cpu_relax();
+ }
+
+ if ( hypercall_preempt_check() )
+ return hypercall3_create_continuation(
+ __HYPERVISOR_console_io, CONSOLEIO_write, count, buffer);
+
+ kcount = min_t(int, count, sizeof(kbuf)-1);
+ if ( copy_from_user(kbuf, buffer, kcount) )
+ return -EFAULT;
+ kbuf[kcount] = '\0';
+
+ serial_puts(sercon_handle, kbuf);
+
+ buffer += kcount;
+ count -= kcount;
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|