diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2010-02-11 21:08:06 +0000 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2010-02-11 21:08:06 +0000 |
commit | c23d905c387ff80a7409d4f66cf91b02fa4297f0 (patch) | |
tree | 1015a9d16525fd8e0210bda78bbaa88f317812a6 /xen/common/keyhandler.c | |
parent | 8eddd7f405d7120aaf284c222e119588275bed3f (diff) | |
download | xen-c23d905c387ff80a7409d4f66cf91b02fa4297f0.tar.gz xen-c23d905c387ff80a7409d4f66cf91b02fa4297f0.tar.bz2 xen-c23d905c387ff80a7409d4f66cf91b02fa4297f0.zip |
keyhandler: global shared scratch space for temporary strings
Put one static definition in one place and we can make it as big as we
think reasonable.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
Diffstat (limited to 'xen/common/keyhandler.c')
-rw-r--r-- | xen/common/keyhandler.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/xen/common/keyhandler.c b/xen/common/keyhandler.c index 9b4d6b7f12..78daf45a3d 100644 --- a/xen/common/keyhandler.c +++ b/xen/common/keyhandler.c @@ -20,19 +20,18 @@ static struct keyhandler *key_table[256]; static unsigned char keypress_key; +char keyhandler_scratch[100]; + static void keypress_action(unsigned long unused) { - unsigned char key = keypress_key; - console_start_log_everything(); - if ( key_table[key] != NULL ) - (*key_table[key]->u.fn)(key); - console_end_log_everything(); + handle_keypress(keypress_key, NULL); } static DECLARE_TASKLET(keypress_tasklet, keypress_action, 0); void handle_keypress(unsigned char key, struct cpu_user_regs *regs) { + static bool_t executing_handler; struct keyhandler *h; if ( (h = key_table[key]) == NULL ) @@ -40,9 +39,18 @@ void handle_keypress(unsigned char key, struct cpu_user_regs *regs) if ( !in_irq() || h->irq_callback ) { + /* + * No concurrent handler execution: prevents garbled console and + * protects keyhandler_scratch[]. + */ + if ( test_and_set_bool(executing_handler) ) + return; + wmb(); console_start_log_everything(); - (*h->u.irq_fn)(key, regs); + h->irq_callback ? (*h->u.irq_fn)(key, regs) : (*h->u.fn)(key); console_end_log_everything(); + wmb(); + executing_handler = 0; } else { @@ -174,7 +182,7 @@ static void dump_domains(unsigned char key) struct domain *d; struct vcpu *v; s_time_t now = NOW(); - char tmpstr[100]; +#define tmpstr keyhandler_scratch printk("'%c' pressed -> dumping domain info (now=0x%X:%08X)\n", key, (u32)(now>>32), (u32)now); @@ -234,6 +242,7 @@ static void dump_domains(unsigned char key) } rcu_read_unlock(&domlist_read_lock); +#undef tmpstr } static struct keyhandler dump_domains_keyhandler = { |