[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] Add a single trigger for all diagnostic keyhandlers



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1249216995 -3600
# Node ID 68e8b8379244e293c55875e7dc3692fc81d3d212
# Parent  a23057f52f147919ab99e9c8c327aa15c12c2510
Add a single trigger for all diagnostic keyhandlers

Add a new keyhandler that triggers all the side-effect-free
keyhandlers.  This lets automated tests (and users) log the full set
of keyhandlers without having to be aware of which ones might reboot
the host.

Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxx>
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 xen/arch/x86/acpi/cpu_idle.c         |    9 +
 xen/arch/x86/hvm/svm/vmcb.c          |    8 +
 xen/arch/x86/hvm/vmx/vmcs.c          |    8 +
 xen/arch/x86/io_apic.c               |    9 +
 xen/arch/x86/irq.c                   |    8 +
 xen/arch/x86/mm/shadow/common.c      |   15 ++
 xen/arch/x86/nmi.c                   |   15 ++
 xen/arch/x86/numa.c                  |    8 +
 xen/common/event_channel.c           |    8 +
 xen/common/kexec.c                   |    7 +
 xen/common/keyhandler.c              |  203 +++++++++++++++++++++++------------
 xen/common/page_alloc.c              |   17 ++
 xen/common/timer.c                   |    7 +
 xen/drivers/char/console.c           |    8 +
 xen/drivers/passthrough/pci.c        |    8 +
 xen/drivers/passthrough/vtd/extern.h |    3 
 xen/drivers/passthrough/vtd/iommu.c  |    2 
 xen/drivers/passthrough/vtd/utils.c  |    8 +
 xen/include/xen/keyhandler.h         |   47 +++++---
 19 files changed, 293 insertions(+), 105 deletions(-)

diff -r a23057f52f14 -r 68e8b8379244 xen/arch/x86/acpi/cpu_idle.c
--- a/xen/arch/x86/acpi/cpu_idle.c      Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/arch/x86/acpi/cpu_idle.c      Sun Aug 02 13:43:15 2009 +0100
@@ -108,10 +108,15 @@ static void dump_cx(unsigned char key)
             print_acpi_power(cpu, processor_powers[cpu]);
 }
 
+static struct keyhandler dump_cx_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = dump_cx,
+    .desc = "dump ACPI Cx structures"
+};
+
 static int __init cpu_idle_key_init(void)
 {
-    register_keyhandler(
-        'c', dump_cx,        "dump ACPI Cx structures");
+    register_keyhandler('c', &dump_cx_keyhandler);
     return 0;
 }
 __initcall(cpu_idle_key_init);
diff -r a23057f52f14 -r 68e8b8379244 xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c       Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/arch/x86/hvm/svm/vmcb.c       Sun Aug 02 13:43:15 2009 +0100
@@ -395,9 +395,15 @@ static void vmcb_dump(unsigned char ch)
     printk("**************************************\n");
 }
 
+static struct keyhandler vmcb_dump_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = vmcb_dump,
+    .desc = "dump AMD-V VMCBs"
+};
+
 void setup_vmcb_dump(void)
 {
-    register_keyhandler('v', vmcb_dump, "dump AMD-V VMCBs");
+    register_keyhandler('v', &vmcb_dump_keyhandler);
 }
 
 /*
diff -r a23057f52f14 -r 68e8b8379244 xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Sun Aug 02 13:43:15 2009 +0100
@@ -1143,9 +1143,15 @@ static void vmcs_dump(unsigned char ch)
     printk("**************************************\n");
 }
 
+static struct keyhandler vmcs_dump_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = vmcs_dump,
+    .desc = "dump Intel's VMCS"
+};
+
 void setup_vmcs_dump(void)
 {
-    register_keyhandler('v', vmcs_dump, "dump Intel's VMCS");
+    register_keyhandler('v', &vmcs_dump_keyhandler);
 }
 
 
diff -r a23057f52f14 -r 68e8b8379244 xen/arch/x86/io_apic.c
--- a/xen/arch/x86/io_apic.c    Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/arch/x86/io_apic.c    Sun Aug 02 13:43:15 2009 +0100
@@ -953,10 +953,15 @@ void print_IO_APIC(void)
         __print_IO_APIC();
 }
 
-void print_IO_APIC_keyhandler(unsigned char key)
+static void _print_IO_APIC_keyhandler(unsigned char key)
 {
     __print_IO_APIC();
 }
+static struct keyhandler print_IO_APIC_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = _print_IO_APIC_keyhandler,
+    .desc = "print ioapic info"
+};
 
 static void __init enable_IO_APIC(void)
 {
@@ -1810,7 +1815,7 @@ void __init setup_IO_APIC(void)
     print_IO_APIC();
     ioapic_pm_state_alloc();
 
-    register_keyhandler('z', print_IO_APIC_keyhandler, "print ioapic info");
+    register_keyhandler('z', &print_IO_APIC_keyhandler);
 }
 
 void ioapic_suspend(void)
diff -r a23057f52f14 -r 68e8b8379244 xen/arch/x86/irq.c
--- a/xen/arch/x86/irq.c        Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/arch/x86/irq.c        Sun Aug 02 13:43:15 2009 +0100
@@ -1139,9 +1139,15 @@ static void dump_irqs(unsigned char key)
     dump_ioapic_irq_info();
 }
 
+static struct keyhandler dump_irqs_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = dump_irqs,
+    .desc = "dump interrupt bindings"
+};
+
 static int __init setup_dump_irqs(void)
 {
-    register_keyhandler('i', dump_irqs, "dump interrupt bindings");
+    register_keyhandler('i', &dump_irqs_keyhandler);
     return 0;
 }
 __initcall(setup_dump_irqs);
diff -r a23057f52f14 -r 68e8b8379244 xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c   Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/arch/x86/mm/shadow/common.c   Sun Aug 02 13:43:15 2009 +0100
@@ -94,10 +94,14 @@ static void shadow_audit_key(unsigned ch
            __func__, shadow_audit_enable);
 }
 
+static struct keyhandler shadow_audit_keyhandler = {
+    .u.fn = shadow_audit_key,
+    .desc = "toggle shadow audits"
+};
+
 static int __init shadow_audit_key_init(void)
 {
-    register_keyhandler(
-        'O', shadow_audit_key,  "toggle shadow audits");
+    register_keyhandler('O', &shadow_audit_keyhandler);
     return 0;
 }
 __initcall(shadow_audit_key_init);
@@ -1482,10 +1486,15 @@ static void shadow_blow_all_tables(unsig
     rcu_read_unlock(&domlist_read_lock);
 }
 
+static struct keyhandler shadow_blow_all_tables_keyhandler = {
+    .u.fn = shadow_blow_all_tables,
+    .desc = "reset shadow pagetables"
+};
+
 /* Register this function in the Xen console keypress table */
 static __init int shadow_blow_tables_keyhandler_init(void)
 {
-    register_keyhandler('S', shadow_blow_all_tables,"reset shadow pagetables");
+    register_keyhandler('S', &shadow_blow_all_tables_keyhandler);
     return 0;
 }
 __initcall(shadow_blow_tables_keyhandler_init);
diff -r a23057f52f14 -r 68e8b8379244 xen/arch/x86/nmi.c
--- a/xen/arch/x86/nmi.c        Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/arch/x86/nmi.c        Sun Aug 02 13:43:15 2009 +0100
@@ -453,6 +453,11 @@ static void do_nmi_trigger(unsigned char
     local_irq_enable();
 }
 
+static struct keyhandler nmi_trigger_keyhandler = {
+    .u.fn = do_nmi_trigger,
+    .desc = "trigger an NMI"
+};
+
 static void do_nmi_stats(unsigned char key)
 {
     int i;
@@ -475,10 +480,16 @@ static void do_nmi_stats(unsigned char k
         printk("dom0 vcpu0: NMI neither pending nor masked\n");
 }
 
+static struct keyhandler nmi_stats_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = do_nmi_stats,
+    .desc = "NMI statistics"
+};
+
 static __init int register_nmi_trigger(void)
 {
-    register_keyhandler('n', do_nmi_trigger, "trigger an NMI");
-    register_keyhandler('N', do_nmi_stats,   "NMI statistics");
+    register_keyhandler('N', &nmi_trigger_keyhandler);
+    register_keyhandler('n', &nmi_stats_keyhandler);
     return 0;
 }
 __initcall(register_nmi_trigger);
diff -r a23057f52f14 -r 68e8b8379244 xen/arch/x86/numa.c
--- a/xen/arch/x86/numa.c       Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/arch/x86/numa.c       Sun Aug 02 13:43:15 2009 +0100
@@ -325,9 +325,15 @@ static void dump_numa(unsigned char key)
        rcu_read_unlock(&domlist_read_lock);
 }
 
+static struct keyhandler dump_numa_keyhandler = {
+       .diagnostic = 1,
+       .u.fn = dump_numa,
+       .desc = "dump numa info"
+};
+
 static __init int register_numa_trigger(void)
 {
-       register_keyhandler('u', dump_numa, "dump numa info");
+       register_keyhandler('u', &dump_numa_keyhandler);
        return 0;
 }
 __initcall(register_numa_trigger);
diff -r a23057f52f14 -r 68e8b8379244 xen/common/event_channel.c
--- a/xen/common/event_channel.c        Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/common/event_channel.c        Sun Aug 02 13:43:15 2009 +0100
@@ -1135,9 +1135,15 @@ static void dump_evtchn_info(unsigned ch
     rcu_read_unlock(&domlist_read_lock);
 }
 
+static struct keyhandler dump_evtchn_info_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = dump_evtchn_info,
+    .desc = "dump evtchn info"
+};
+
 static int __init dump_evtchn_info_key_init(void)
 {
-    register_keyhandler('e', dump_evtchn_info, "dump evtchn info");
+    register_keyhandler('e', &dump_evtchn_info_keyhandler);
     return 0;
 }
 __initcall(dump_evtchn_info_key_init);
diff -r a23057f52f14 -r 68e8b8379244 xen/common/kexec.c
--- a/xen/common/kexec.c        Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/common/kexec.c        Sun Aug 02 13:43:15 2009 +0100
@@ -133,9 +133,14 @@ static void do_crashdump_trigger(unsigne
     printk(" * no crash kernel loaded!\n");
 }
 
+static struct keyhandler crashdump_trigger_keyhandler = {
+    .u.fn = do_crashdump_trigger,
+    .desc = "trigger a crashdump"
+};
+
 static __init int register_crashdump_trigger(void)
 {
-    register_keyhandler('C', do_crashdump_trigger, "trigger a crashdump");
+    register_keyhandler('C', &crashdump_trigger_keyhandler);
     return 0;
 }
 __initcall(register_crashdump_trigger);
diff -r a23057f52f14 -r 68e8b8379244 xen/common/keyhandler.c
--- a/xen/common/keyhandler.c   Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/common/keyhandler.c   Sun Aug 02 13:43:15 2009 +0100
@@ -13,32 +13,19 @@
 #include <xen/domain.h>
 #include <xen/rangeset.h>
 #include <xen/compat.h>
+#include <xen/ctype.h>
 #include <asm/debugger.h>
 #include <asm/div64.h>
 
-#define KEY_MAX 256
-#define STR_MAX  64
-
-static struct {
-    union {
-        keyhandler_t     *handler;
-        irq_keyhandler_t *irq_handler;
-    } u;
-    unsigned int flags;
-    char         desc[STR_MAX];
-} key_table[KEY_MAX];
-
-#define KEYHANDLER_IRQ_CALLBACK 0x1
-
+static struct keyhandler *key_table[256];
 static unsigned char keypress_key;
 
 static void keypress_action(unsigned long unused)
 {
-    keyhandler_t *h;
     unsigned char key = keypress_key;
     console_start_log_everything();
-    if ( (h = key_table[key].u.handler) != NULL )
-        (*h)(key);
+    if ( key_table[key] != NULL )
+        (*key_table[key]->u.fn)(key);
     console_end_log_everything();
 }
 
@@ -46,13 +33,15 @@ static DECLARE_TASKLET(keypress_tasklet,
 
 void handle_keypress(unsigned char key, struct cpu_user_regs *regs)
 {
-    irq_keyhandler_t *h;
-
-    if ( !in_irq() || (key_table[key].flags & KEYHANDLER_IRQ_CALLBACK) )
+    struct keyhandler *h;
+
+    if ( (h = key_table[key]) == NULL )
+        return;
+
+    if ( !in_irq() || h->irq_callback )
     {
         console_start_log_everything();
-        if ( (h = key_table[key].u.irq_handler) != NULL )
-            (*h)(key, regs);
+        (*h->u.irq_fn)(key, regs);
         console_end_log_everything();
     }
     else
@@ -62,34 +51,26 @@ void handle_keypress(unsigned char key, 
     }
 }
 
-void register_keyhandler(
-    unsigned char key, keyhandler_t *handler, char *desc)
-{
-    ASSERT(key_table[key].u.handler == NULL);
-    key_table[key].u.handler = handler;
-    key_table[key].flags     = 0;
-    safe_strcpy(key_table[key].desc, desc);
-}
-
-void register_irq_keyhandler(
-    unsigned char key, irq_keyhandler_t *handler, char *desc)
-{
-    ASSERT(key_table[key].u.irq_handler == NULL);
-    key_table[key].u.irq_handler = handler;
-    key_table[key].flags         = KEYHANDLER_IRQ_CALLBACK;
-    safe_strcpy(key_table[key].desc, desc);
+void register_keyhandler(unsigned char key, struct keyhandler *handler)
+{
+    ASSERT(key_table[key] == NULL);
+    key_table[key] = handler;
 }
 
 static void show_handlers(unsigned char key)
 {
     int i;
     printk("'%c' pressed -> showing installed handlers\n", key);
-    for ( i = 0; i < KEY_MAX; i++ ) 
-        if ( key_table[i].u.handler != NULL ) 
+    for ( i = 0; i < ARRAY_SIZE(key_table); i++ ) 
+        if ( key_table[i] != NULL ) 
             printk(" key '%c' (ascii '%02x') => %s\n", 
-                   (i<33 || i>126)?(' '):(i),i,
-                   key_table[i].desc);
-}
+                   isprint(i) ? i : ' ', i, key_table[i]->desc);
+}
+
+static struct keyhandler show_handlers_keyhandler = {
+    .u.fn = show_handlers,
+    .desc = "show this message"
+};
 
 static void __dump_execstate(void *unused)
 {
@@ -127,6 +108,13 @@ static void dump_registers(unsigned char
     console_end_sync();
 }
 
+static struct keyhandler dump_registers_keyhandler = {
+    .irq_callback = 1,
+    .diagnostic = 1,
+    .u.irq_fn = dump_registers,
+    .desc = "dump registers"
+};
+
 static void dump_dom0_registers(unsigned char key)
 {
     struct vcpu *v;
@@ -140,11 +128,23 @@ static void dump_dom0_registers(unsigned
         vcpu_show_execution_state(v);
 }
 
-static void halt_machine(unsigned char key, struct cpu_user_regs *regs)
+static struct keyhandler dump_dom0_registers_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = dump_dom0_registers,
+    .desc = "dump Dom0 registers"
+};
+
+static void reboot_machine(unsigned char key, struct cpu_user_regs *regs)
 {
     printk("'%c' pressed -> rebooting machine\n", key);
     machine_restart(0);
 }
+
+static struct keyhandler reboot_machine_keyhandler = {
+    .irq_callback = 1,
+    .u.irq_fn = reboot_machine,
+    .desc = "reboot machine"
+};
 
 static void cpuset_print(char *set, int size, cpumask_t mask)
 {
@@ -236,6 +236,12 @@ static void dump_domains(unsigned char k
     rcu_read_unlock(&domlist_read_lock);
 }
 
+static struct keyhandler dump_domains_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = dump_domains,
+    .desc = "dump domain (and guest debug) info"
+};
+
 static cpumask_t read_clocks_cpumask = CPU_MASK_NONE;
 static s_time_t read_clocks_time[NR_CPUS];
 static u64 read_cycles_time[NR_CPUS];
@@ -314,12 +320,82 @@ static void read_clocks(unsigned char ke
            maxdif_cycles, sumdif_cycles/count, count, dif_cycles);
 }
 
+static struct keyhandler read_clocks_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = read_clocks,
+    .desc = "display multi-cpu clock info"
+};
+
 extern void dump_runq(unsigned char key);
+static struct keyhandler dump_runq_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = dump_runq,
+    .desc = "dump run queues"
+};
 
 #ifdef PERF_COUNTERS
 extern void perfc_printall(unsigned char key);
+static struct keyhandler perfc_printall_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = perfc_printall,
+    .desc = "print performance counters"
+};
 extern void perfc_reset(unsigned char key);
+static struct keyhandler perfc_reset_keyhandler = {
+    .u.fn = perfc_reset,
+    .desc = "reset performance counters"
+};
 #endif
+
+static void run_all_nonirq_keyhandlers(unsigned long unused)
+{
+    /* Fire all the non-IRQ-context diagnostic keyhandlers */
+    struct keyhandler *h;
+    int k;
+
+    console_start_log_everything();
+    for ( k = 0; k < ARRAY_SIZE(key_table); k++ )
+    {
+        h = key_table[k];
+        if ( (h == NULL) || !h->diagnostic || h->irq_callback )
+            continue;
+        printk("[%c: %s]\n", k, h->desc);
+        (*h->u.fn)(k);
+    }
+    console_end_log_everything();
+}
+
+static DECLARE_TASKLET(run_all_keyhandlers_tasklet,
+                       run_all_nonirq_keyhandlers, 0);
+
+static void run_all_keyhandlers(unsigned char key, struct cpu_user_regs *regs)
+{
+    struct keyhandler *h;
+    int k;
+
+    printk("'%c' pressed -> firing all diagnostic keyhandlers\n", key);
+
+    /* Fire all the IRQ-context diangostic keyhandlers now */
+    console_start_log_everything();
+    for ( k = 0; k < ARRAY_SIZE(key_table); k++ )
+    {
+        h = key_table[k];
+        if ( (h == NULL) || !h->diagnostic || !h->irq_callback )
+            continue;
+        printk("[%c: %s]\n", k, h->desc);
+        (*h->u.irq_fn)(k, regs);
+    }
+    console_end_log_everything();
+
+    /* Trigger the others from a tasklet in non-IRQ context */
+    tasklet_schedule(&run_all_keyhandlers_tasklet);
+}
+
+static struct keyhandler run_all_keyhandlers_keyhandler = {
+    .irq_callback = 1,
+    .u.irq_fn = run_all_keyhandlers,
+    .desc = "print all diagnostics"
+};
 
 static void do_debug_key(unsigned char key, struct cpu_user_regs *regs)
 {
@@ -330,33 +406,28 @@ static void do_debug_key(unsigned char k
                              bit. */
 }
 
+static struct keyhandler do_debug_key_keyhandler = {
+    .irq_callback = 1,
+    .u.irq_fn = do_debug_key,
+    .desc = "trap to xendbg"
+};
+
 void __init initialize_keytable(void)
 {
-    register_irq_keyhandler(
-        'd', dump_registers, "dump registers");
-    register_keyhandler(
-        'h', show_handlers, "show this message");
-    register_keyhandler(
-        'q', dump_domains, "dump domain (and guest debug) info");
-    register_keyhandler(
-        'r', dump_runq,      "dump run queues");
-    register_irq_keyhandler(
-        'R', halt_machine,   "reboot machine");
-
-    register_keyhandler(
-        't', read_clocks, "display multi-cpu clock info");
+    register_keyhandler('d', &dump_registers_keyhandler);
+    register_keyhandler('h', &show_handlers_keyhandler);
+    register_keyhandler('q', &dump_domains_keyhandler);
+    register_keyhandler('r', &dump_runq_keyhandler);
+    register_keyhandler('R', &reboot_machine_keyhandler);
+    register_keyhandler('t', &read_clocks_keyhandler);
+    register_keyhandler('0', &dump_dom0_registers_keyhandler);
+    register_keyhandler('%', &do_debug_key_keyhandler);
+    register_keyhandler('*', &run_all_keyhandlers_keyhandler);
 
 #ifdef PERF_COUNTERS
-    register_keyhandler(
-        'p', perfc_printall, "print performance counters");
-    register_keyhandler(
-        'P', perfc_reset,    "reset performance counters");
+    register_keyhandler('p', &perfc_printall_keyhandler);
+    register_keyhandler('P', &perfc_reset_keyhandler);
 #endif
-
-    register_keyhandler(
-        '0', dump_dom0_registers, "dump Dom0 registers");
-
-    register_irq_keyhandler('%', do_debug_key,   "Trap to xendbg");
 }
 
 /*
diff -r a23057f52f14 -r 68e8b8379244 xen/common/page_alloc.c
--- a/xen/common/page_alloc.c   Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/common/page_alloc.c   Sun Aug 02 13:43:15 2009 +0100
@@ -1192,7 +1192,7 @@ unsigned long avail_domheap_pages(void)
                             -1);
 }
 
-static void pagealloc_keyhandler(unsigned char key)
+static void pagealloc_info(unsigned char key)
 {
     unsigned int zone = MEMZONE_XEN;
     unsigned long n, total = 0;
@@ -1219,10 +1219,15 @@ static void pagealloc_keyhandler(unsigne
     printk("    Dom heap: %lukB free\n", total << (PAGE_SHIFT-10));
 }
 
+static struct keyhandler pagealloc_info_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = pagealloc_info,
+    .desc = "memory info"
+};
 
 static __init int pagealloc_keyhandler_init(void)
 {
-    register_keyhandler('m', pagealloc_keyhandler, "memory info");
+    register_keyhandler('m', &pagealloc_info_keyhandler);
     return 0;
 }
 __initcall(pagealloc_keyhandler_init);
@@ -1261,9 +1266,15 @@ static void dump_heap(unsigned char key)
     }
 }
 
+static struct keyhandler dump_heap_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = dump_heap,
+    .desc = "dump heap info"
+};
+
 static __init int register_heap_trigger(void)
 {
-    register_keyhandler('H', dump_heap, "dump heap info");
+    register_keyhandler('H', &dump_heap_keyhandler);
     return 0;
 }
 __initcall(register_heap_trigger);
diff -r a23057f52f14 -r 68e8b8379244 xen/common/timer.c
--- a/xen/common/timer.c        Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/common/timer.c        Sun Aug 02 13:43:15 2009 +0100
@@ -514,6 +514,11 @@ static void dump_timerq(unsigned char ke
     }
 }
 
+static struct keyhandler dump_timerq_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = dump_timerq,
+    .desc = "dump timer queues"
+};
 
 void __init timer_init(void)
 {
@@ -535,7 +540,7 @@ void __init timer_init(void)
         per_cpu(timers, i).heap = &dummy_heap;
     }
 
-    register_keyhandler('a', dump_timerq, "dump timer queues");
+    register_keyhandler('a', &dump_timerq_keyhandler);
 }
 
 /*
diff -r a23057f52f14 -r 68e8b8379244 xen/drivers/char/console.c
--- a/xen/drivers/char/console.c        Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/drivers/char/console.c        Sun Aug 02 13:43:15 2009 +0100
@@ -921,6 +921,11 @@ static void debugtrace_key(unsigned char
     debugtrace_toggle();
 }
 
+static struct keyhandler debugtrace_keyhandler = {
+    .u.fn = debugtrace_key,
+    .desc = "toggle debugtrace to console/buffer"
+};
+
 static int __init debugtrace_init(void)
 {
     int order;
@@ -942,8 +947,7 @@ static int __init debugtrace_init(void)
 
     debugtrace_bytes = bytes;
 
-    register_keyhandler(
-        'T', debugtrace_key, "toggle debugtrace to console/buffer");
+    register_keyhandler('T', &debugtrace_keyhandler);
 
     return 0;
 }
diff -r a23057f52f14 -r 68e8b8379244 xen/drivers/passthrough/pci.c
--- a/xen/drivers/passthrough/pci.c     Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/drivers/passthrough/pci.c     Sun Aug 02 13:43:15 2009 +0100
@@ -415,9 +415,15 @@ static void dump_pci_devices(unsigned ch
     spin_unlock(&pcidevs_lock);
 }
 
+struct keyhandler dump_pci_devices_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = dump_pci_devices,
+    .desc = "dump PCI devices"
+};
+
 static int __init setup_dump_pcidevs(void)
 {
-    register_keyhandler('Q', dump_pci_devices, "dump PCI devices");
+    register_keyhandler('Q', &dump_pci_devices_keyhandler);
     return 0;
 }
 __initcall(setup_dump_pcidevs);
diff -r a23057f52f14 -r 68e8b8379244 xen/drivers/passthrough/vtd/extern.h
--- a/xen/drivers/passthrough/vtd/extern.h      Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/drivers/passthrough/vtd/extern.h      Sun Aug 02 13:43:15 2009 +0100
@@ -22,13 +22,14 @@
 #define _VTD_EXTERN_H_
 
 #include "dmar.h"
+#include <xen/keyhandler.h>
 
 extern int qinval_enabled;
 extern int ats_enabled;
 
 void print_iommu_regs(struct acpi_drhd_unit *drhd);
 void print_vtd_entries(struct iommu *iommu, int bus, int devfn, u64 gmfn);
-void dump_iommu_info(unsigned char key);
+extern struct keyhandler dump_iommu_info_keyhandler;
 
 int enable_qinval(struct iommu *iommu);
 void disable_qinval(struct iommu *iommu);
diff -r a23057f52f14 -r 68e8b8379244 xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c       Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/drivers/passthrough/vtd/iommu.c       Sun Aug 02 13:43:15 2009 +0100
@@ -1759,7 +1759,7 @@ int intel_vtd_setup(void)
     if ( init_vtd_hw() )
         goto error;
 
-    register_keyhandler('V', dump_iommu_info, "dump iommu info");
+    register_keyhandler('V', &dump_iommu_info_keyhandler);
 
     return 0;
 
diff -r a23057f52f14 -r 68e8b8379244 xen/drivers/passthrough/vtd/utils.c
--- a/xen/drivers/passthrough/vtd/utils.c       Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/drivers/passthrough/vtd/utils.c       Sun Aug 02 13:43:15 2009 +0100
@@ -194,7 +194,7 @@ void print_vtd_entries(struct iommu *iom
     } while ( --level );
 }
 
-void dump_iommu_info(unsigned char key)
+static void dump_iommu_info(unsigned char key)
 {
 #if defined(__i386__) || defined(__x86_64__)
     struct acpi_drhd_unit *drhd;
@@ -304,6 +304,12 @@ void dump_iommu_info(unsigned char key)
 #endif
 }
 
+struct keyhandler dump_iommu_info_keyhandler = {
+    .diagnostic = 1,
+    .u.fn = dump_iommu_info,
+    .desc = "dump iommu info"
+};
+
 /*
  * Local variables:
  * mode: C
diff -r a23057f52f14 -r 68e8b8379244 xen/include/xen/keyhandler.h
--- a/xen/include/xen/keyhandler.h      Sun Aug 02 12:29:25 2009 +0100
+++ b/xen/include/xen/keyhandler.h      Sun Aug 02 13:43:15 2009 +0100
@@ -10,25 +10,44 @@
 #ifndef __XEN_KEYHANDLER_H__
 #define __XEN_KEYHANDLER_H__
 
+typedef void keyhandler_fn_t(
+    unsigned char key);
+typedef void irq_keyhandler_fn_t(
+    unsigned char key, struct cpu_user_regs *regs);
+
+struct keyhandler {
+    /*
+     * If TRUE then u.irq_fn is called in hardirq context with interrupts
+     * disabled. The @regs callback parameter points at the interrupted
+     * register context. 
+     * If FALSE then u.fn is called in softirq context with no locks held and
+     * interrupts enabled.
+     */
+    bool_t irq_callback;
+
+    /*
+     * If TRUE then the keyhandler will be included in the "dump everything"
+     * keyhandler, so must not have any side-effects.
+     */
+    bool_t diagnostic;
+
+    union {
+        keyhandler_fn_t *fn;
+        irq_keyhandler_fn_t *irq_fn;
+    } u;
+
+    /* The string is not copied by register_keyhandler(), so must persist. */
+    char *desc;
+};
+
 /* Initialize keytable with default handlers */
 extern void initialize_keytable(void);
 
 /*
- * Register a callback function for key @key. The callback occurs in
- * softirq context with no locks held and interrupts enabled.
+ * Register a callback handler for key @key. The keyhandler structure is not
+ * copied, so must persist.
  */
-typedef void keyhandler_t(unsigned char key);
-extern void register_keyhandler(
-    unsigned char key, keyhandler_t *handler, char *desc);
-
-/*
- * Register an IRQ callback function for key @key. The callback occurs
- * synchronously in hard-IRQ context with interrupts disabled. The @regs
- * callback parameter points at the interrupted register context.
- */
-typedef void irq_keyhandler_t(unsigned char key, struct cpu_user_regs *regs);
-extern void register_irq_keyhandler(
-    unsigned char key, irq_keyhandler_t *handler, char *desc);
+extern void register_keyhandler(unsigned char key, struct keyhandler *handler);
 
 /* Inject a keypress into the key-handling subsystem. */
 extern void handle_keypress(unsigned char key, struct cpu_user_regs *regs);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.