aboutsummaryrefslogtreecommitdiffstats
path: root/xen/drivers/char
diff options
context:
space:
mode:
authorMatt Wilson <msw@amazon.com>2012-10-01 20:02:45 +0100
committerMatt Wilson <msw@amazon.com>2012-10-01 20:02:45 +0100
commit44499c683f349462465ee9151090e2af1bda71d3 (patch)
tree34ee645869d4708d3746775b96d575e5f08e2abc /xen/drivers/char
parent45f52f2646a5ad9092d94eb9474657b5b3e04025 (diff)
downloadxen-44499c683f349462465ee9151090e2af1bda71d3.tar.gz
xen-44499c683f349462465ee9151090e2af1bda71d3.tar.bz2
xen-44499c683f349462465ee9151090e2af1bda71d3.zip
xen/console: introduce a 'w' debug-key that dumps the console ring
This patch adds a new 'w' debug-key, chosen from the limited remaining keys only due to its proximity to 'q', that dumps the console ring to configured console devices. It's useful to for tracking down how an unresponsive system got into a broken state via serial console. Signed-off-by: Matt Wilson <msw@amazon.com> Committed-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/drivers/char')
-rw-r--r--xen/drivers/char/console.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c
index d97170c641..9e1adb50f7 100644
--- a/xen/drivers/char/console.c
+++ b/xen/drivers/char/console.c
@@ -264,6 +264,49 @@ static void sercon_puts(const char *s)
serial_puts(sercon_handle, s);
}
+static void dump_console_ring_key(unsigned char key)
+{
+ uint32_t idx, len, sofar, c;
+ unsigned int order;
+ char *buf;
+
+ printk("'%c' pressed -> dumping console ring buffer (dmesg)\n", key);
+
+ /* create a buffer in which we'll copy the ring in the correct
+ order and NUL terminate */
+ order = get_order_from_bytes(conring_size + 1);
+ buf = alloc_xenheap_pages(order, 0);
+ if ( buf == NULL )
+ {
+ printk("unable to allocate memory!\n");
+ return;
+ }
+
+ c = conringc;
+ sofar = 0;
+ while ( (c != conringp) )
+ {
+ idx = CONRING_IDX_MASK(c);
+ len = conringp - c;
+ if ( (idx + len) > conring_size )
+ len = conring_size - idx;
+ memcpy(buf + sofar, &conring[idx], len);
+ sofar += len;
+ c += len;
+ }
+ buf[sofar] = '\0';
+
+ sercon_puts(buf);
+ vga_puts(buf);
+
+ free_xenheap_pages(buf, order);
+}
+
+static struct keyhandler dump_console_ring_keyhandler = {
+ .u.fn = dump_console_ring_key,
+ .desc = "synchronously dump console ring buffer (dmesg)"
+};
+
/* CTRL-<switch_char> switches input direction between Xen and DOM0. */
#define switch_code (opt_conswitch[0]-'a'+1)
static int __read_mostly xen_rx = 1; /* FALSE => serial input passed to domain 0. */
@@ -661,6 +704,8 @@ void __init console_endboot(void)
if ( opt_conswitch[1] == 'x' )
xen_rx = !xen_rx;
+ register_keyhandler('w', &dump_console_ring_keyhandler);
+
/* Serial input is directed to DOM0 by default. */
switch_serial_input();
}