[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |