x86/tracing changes for v3.11
Subsystems (6)
Linus,
Please pull the latest x86-tracing-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-tracing-for-linus
HEAD: 5236eb968ec21c693d463d0494e39b00c1bc174d Merge remote-tracking branch 'trace/tip/x86/trace' into x86/trace
This tree adds IRQ vector tracepoints that are named after the handler and which output the vector #, based on a zero-overhead approach that relies on changing the IDT entries, by Seiji Aguchi.
The new tracepoints look like this:
# perf list | grep -i irq_vector irq_vectors:local_timer_entry [Tracepoint event] irq_vectors:local_timer_exit [Tracepoint event] irq_vectors:reschedule_entry [Tracepoint event] irq_vectors:reschedule_exit [Tracepoint event] irq_vectors:spurious_apic_entry [Tracepoint event] irq_vectors:spurious_apic_exit [Tracepoint event] irq_vectors:error_apic_entry [Tracepoint event] irq_vectors:error_apic_exit [Tracepoint event] [...]
out-of-topic modifications in x86-tracing-for-linus:
----------------------------------------------------
include/linux/tracepoint.h # f5abaa1: tracing: Add DEFINE_EVENT_FN() ma include/trace/define_trace.h # f5abaa1: tracing: Add DEFINE_EVENT_FN() ma include/trace/ftrace.h # f5abaa1: tracing: Add DEFINE_EVENT_FN() ma
Thanks,
Ingo
------------------>
Seiji Aguchi (4):
x86, trace: Introduce entering/exiting_irq()
x86: Rename variables for debugging
x86, trace: Add irq vector tracepoints
x86/tracing: Add config option checking to the definitions of mce handlers
Steven Rostedt (1):
tracing: Add DEFINE_EVENT_FN() macro
Steven Rostedt (Red Hat) (2):
trace,x86: Move creation of irq tracepoints from apic.c to irq.c trace,x86: Do not call local_irq_save() in load_current_idt()
arch/x86/include/asm/apic.h | 27 +++++++ arch/x86/include/asm/desc.h | 117 +++++++++++++++++++++++++++++-- arch/x86/include/asm/entry_arch.h | 8 ++- arch/x86/include/asm/hw_irq.h | 17 +++++ arch/x86/include/asm/mshyperv.h | 3 + arch/x86/include/asm/trace/irq_vectors.h | 104 +++++++++++++++++++++++++++ arch/x86/include/asm/uv/uv_bau.h | 3 + arch/x86/kernel/Makefile | 3 + arch/x86/kernel/apic/apic.c | 69 ++++++++++++++---- arch/x86/kernel/cpu/common.c | 20 +++--- arch/x86/kernel/cpu/mcheck/therm_throt.c | 24 +++++-- arch/x86/kernel/cpu/mcheck/threshold.c | 24 +++++-- arch/x86/kernel/entry_32.S | 12 +++- arch/x86/kernel/entry_64.S | 36 ++++++++-- arch/x86/kernel/head_64.S | 8 ++- arch/x86/kernel/irq.c | 33 ++++++--- arch/x86/kernel/irq_work.c | 24 ++++++- arch/x86/kernel/smp.c | 65 ++++++++++++++--- arch/x86/kernel/tracepoint.c | 61 ++++++++++++++++ arch/x86/kernel/traps.c | 2 +- include/linux/tracepoint.h | 2 + include/trace/define_trace.h | 5 ++ include/trace/ftrace.h | 4 ++ include/xen/events.h | 3 + 24 files changed, 602 insertions(+), 72 deletions(-) create mode 100644 arch/x86/include/asm/trace/irq_vectors.h create mode 100644 arch/x86/kernel/tracepoint.c
arch/x86/include/asm/apic.h +27 -0
@@ -12,6 +12,7 @@#include <asm/fixmap.h> #include <asm/mpspec.h> #include <asm/msr.h> +#include <asm/idle.h> #define ARCH_APICTIMER_STOPS_ON_C3 1
@@ -687,5 +688,31 @@ extern int default_check_phys_apicid_present(int phys_apicid);#endif #endif /* CONFIG_X86_LOCAL_APIC */ +extern void irq_enter (void ); +extern void irq_exit (void ); + +static inline void entering_irq (void ) +{ +irq_enter (); +exit_idle (); +} + +static inline void entering_ack_irq (void ) +{ +ack_APIC_irq (); +entering_irq (); +} + +static inline void exiting_irq (void ) +{ +irq_exit (); +} + +static inline void exiting_ack_irq (void ) +{ +irq_exit (); +/* Ack only at the end to avoid potential reentry */ +ack_APIC_irq (); +}#endif /* _ASM_X86_APIC_H */
arch/x86/include/asm/desc.h +112 -5
149 lines not on this page · raw message
arch/x86/include/asm/entry_arch.h +5 -3
@@ -13,14 +13,16 @@ BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR) BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR) -BUILD_INTERRUPT(irq_move_cleanup_interrupt,IRQ_MOVE_CLEANUP_VECTOR) -BUILD_INTERRUPT(reboot_interrupt,REBOOT_VECTOR) +BUILD_INTERRUPT3 (irq_move_cleanup_interrupt,IRQ_MOVE_CLEANUP_VECTOR , + smp_irq_move_cleanup_interrupt) +BUILD_INTERRUPT3(reboot_interrupt, REBOOT_VECTOR, smp_reboot_interrupt)#endif BUILD_INTERRUPT(x86_platform_ipi, X86_PLATFORM_IPI_VECTOR)#ifdef CONFIG_HAVE_KVM -BUILD_INTERRUPT(kvm_posted_intr_ipi, POSTED_INTR_VECTOR) +BUILD_INTERRUPT3 (kvm_posted_intr_ipi,POSTED_INTR_VECTOR , + smp_kvm_posted_intr_ipi)#endif /*
arch/x86/include/asm/hw_irq.h +17 -0
@@ -77,6 +77,23 @@ extern void threshold_interrupt(void);extern void call_function_interrupt (void );extern void call_function_single_interrupt (void ); +#ifdef CONFIG_TRACING +/* Interrupt handlers registered during init_IRQ */ +extern void trace_apic_timer_interrupt (void ); +extern void trace_x86_platform_ipi (void ); +extern void trace_error_interrupt (void ); +extern void trace_irq_work_interrupt (void ); +extern void trace_spurious_interrupt (void ); +extern void trace_thermal_interrupt (void ); +extern void trace_reschedule_interrupt (void ); +extern void trace_threshold_interrupt (void ); +extern void trace_call_function_interrupt (void ); +extern void trace_call_function_single_interrupt (void ); +#define trace_irq_move_cleanup_interrupt irq_move_cleanup_interrupt +#define trace_reboot_interrupt reboot_interrupt +#define trace_kvm_posted_intr_ipi kvm_posted_intr_ipi +#endif /* CONFIG_TRACING */ +/* IOAPIC */ #define IO_APIC_IRQ (x) (((x) >= NR_IRQS_LEGACY) || ((1<<(x)) & io_apic_irqs))extern unsigned long io_apic_irqs;
arch/x86/include/asm/mshyperv.h +3 -0
@@ -12,6 +12,9 @@ struct ms_hyperv_info {extern struct ms_hyperv_info ms_hyperv;void hyperv_callback_vector (void ); +#ifdef CONFIG_TRACING +#define trace_hyperv_callback_vector hyperv_callback_vector +#endif void hyperv_vector_handler (struct pt_regs *regs);void hv_register_vmbus_handler (int irq,irq_handler_t handler);
arch/x86/include/asm/trace/irq_vectors.h new file +104 -0
104 lines not on this page · raw message
arch/x86/include/asm/uv/uv_bau.h +3 -0
@@ -731,6 +731,9 @@ static inline void bau_cpubits_clear(struct bau_local_cpumask *dstp, int nbits) }extern void uv_bau_message_intr1 (void ); +#ifdef CONFIG_TRACING +#define trace_uv_bau_message_intr1 uv_bau_message_intr1 +#endif extern void uv_bau_timeout_intr1 (void );struct atomic_short {
arch/x86/kernel/Makefile +3 -0
@@ -16,6 +16,8 @@ CFLAGS_REMOVE_ftrace.o = -pg CFLAGS_REMOVE_early_printk.o = -pg endif +CFLAGS_irq.o := -I$(src)/../include/asm/trace + obj-y := process_$(BITS).o signal.o entry_$(BITS).o obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o obj-y += time.o ioport.o ldt.o dumpstack.o nmi.o
@@ -102,6 +104,7 @@ obj-$(CONFIG_OF) += devicetree.o obj-$(CONFIG_UPROBES) += uprobes.o obj-$(CONFIG_PERF_EVENTS) += perf_regs.o +obj-$(CONFIG_TRACING) += tracepoint.o ### # 64 bit specific files
arch/x86/kernel/apic/apic.c +57 -12
120 lines not on this page · raw message
arch/x86/kernel/cpu/common.c +10 -10
@@ -1071,8 +1071,8 @@ __setup("clearcpuid=", setup_disablecpuid);#ifdef CONFIG_X86_64 struct desc_ptr idt_descr = {NR_VECTORS *16 -1 , (unsigned long ) idt_table }; -struct desc_ptr nmi_idt_descr = {NR_VECTORS *16 -1 , - (unsigned long ) nmi_idt_table }; +struct desc_ptr debug_idt_descr = {NR_VECTORS *16 -1 , + (unsigned long ) debug_idt_table }; DEFINE_PER_CPU_FIRST(union irq_stack_union, irq_stack_union)__aligned(PAGE_SIZE) ;
@@ -1148,20 +1148,20 @@ int is_debug_stack(unsigned long addr) addr > (__get_cpu_var(debug_stack_addr) - DEBUG_STKSZ)); } -static DEFINE_PER_CPU(u32, debug_stack_use_ctr); +DEFINE_PER_CPU (u32, debug_idt_ctr);void debug_stack_set_zero (void ) { -this_cpu_inc (debug_stack_use_ctr); -load_idt ((const struct desc_ptr *)&nmi_idt_descr); +this_cpu_inc (debug_idt_ctr); +load_current_idt (); }void debug_stack_reset (void ) { -if (WARN_ON (!this_cpu_read (debug_stack_use_ctr))) +if (WARN_ON (!this_cpu_read (debug_idt_ctr)))return ; -if (this_cpu_dec_return (debug_stack_use_ctr) ==0 ) -load_idt ((const struct desc_ptr *)&idt_descr); +if (this_cpu_dec_return (debug_idt_ctr) ==0 ) +load_current_idt (); }#else /* CONFIG_X86_64 */
@@ -1257,7 +1257,7 @@ void __cpuinit cpu_init(void)switch_to_new_gdt (cpu);loadsegment (fs,0 ); -load_idt ((const struct desc_ptr *)&idt_descr); +load_current_idt ();memset (me->thread.tls_array,0 ,GDT_ENTRY_TLS_ENTRIES *8 );syscall_init ();
@@ -1334,7 +1334,7 @@ void __cpuinit cpu_init(void)if (cpu_has_vme || cpu_has_tsc || cpu_has_de)clear_in_cr4 (X86_CR4_VME |X86_CR4_PVI |X86_CR4_TSD |X86_CR4_DE ); -load_idt (&idt_descr); +load_current_idt ();switch_to_new_gdt (cpu);/*
arch/x86/kernel/cpu/mcheck/therm_throt.c +18 -6
@@ -29,6 +29,7 @@#include <asm/idle.h> #include <asm/mce.h> #include <asm/msr.h> +#include <asm/trace/irq_vectors.h> /* How long to wait between reporting thermal events */ #define CHECK_INTERVAL (300 * HZ)
@@ -378,15 +379,26 @@ static void unexpected_thermal_interrupt(void)static void (*smp_thermal_vector)(void ) = unexpected_thermal_interrupt; -asmlinkage void smp_thermal_interrupt(struct pt_regs *regs) +static inline void __smp_thermal_interrupt (void ) { -irq_enter (); -exit_idle ();inc_irq_stat (irq_thermal_count);smp_thermal_vector (); -irq_exit (); -/* Ack only at the end to avoid potential reentry */ -ack_APIC_irq (); +} + +asmlinkage void smp_thermal_interrupt(struct pt_regs *regs) +{ +entering_irq (); +__smp_thermal_interrupt (); +exiting_ack_irq (); +} + +asmlinkage void smp_trace_thermal_interrupt(struct pt_regs *regs) +{ +entering_irq (); +trace_thermal_apic_entry (THERMAL_APIC_VECTOR ); +__smp_thermal_interrupt (); +trace_thermal_apic_exit (THERMAL_APIC_VECTOR ); +exiting_ack_irq (); }/* Thermal monitoring depends on APIC, ACPI and clock modulation */
arch/x86/kernel/cpu/mcheck/threshold.c +18 -6
@@ -8,6 +8,7 @@#include <asm/apic.h> #include <asm/idle.h> #include <asm/mce.h> +#include <asm/trace/irq_vectors.h> static void default_threshold_interrupt (void ) {
@@ -17,13 +18,24 @@ static void default_threshold_interrupt(void)void (*mce_threshold_vector)(void ) = default_threshold_interrupt; -asmlinkage void smp_threshold_interrupt(void) +static inline void __smp_threshold_interrupt (void ) { -irq_enter (); -exit_idle ();inc_irq_stat (irq_threshold_count);mce_threshold_vector (); -irq_exit (); -/* Ack only at the end to avoid potential reentry */ -ack_APIC_irq (); +} + +asmlinkage void smp_threshold_interrupt(void) +{ +entering_irq (); +__smp_threshold_interrupt (); +exiting_ack_irq (); +} + +asmlinkage void smp_trace_threshold_interrupt(void) +{ +entering_irq (); +trace_threshold_apic_entry (THRESHOLD_APIC_VECTOR ); +__smp_threshold_interrupt (); +trace_threshold_apic_exit (THRESHOLD_APIC_VECTOR ); +exiting_ack_irq (); }
arch/x86/kernel/entry_32.S +11 -1
@@ -801,7 +801,17 @@ ENTRY(name) \ CFI_ENDPROC; \ ENDPROC(name) -#define BUILD_INTERRUPT(name, nr) BUILD_INTERRUPT3(name, nr, smp_##name) + +#ifdef CONFIG_TRACING +#define TRACE_BUILD_INTERRUPT(name, nr) \ + BUILD_INTERRUPT3(trace_##name, nr, smp_trace_##name) +#else +#define TRACE_BUILD_INTERRUPT(name, nr) +#endif + +#define BUILD_INTERRUPT(name, nr) \ + BUILD_INTERRUPT3(name, nr, smp_##name); \ + TRACE_BUILD_INTERRUPT(name, nr) /* The include is where all of the SMP etc. interrupts come from */ #include <asm/entry_arch.h>
arch/x86/kernel/entry_64.S +29 -7
@@ -1138,7 +1138,7 @@ END(common_interrupt) /* * APIC interrupts. */ -.macro apicinterrupt num sym do_sym +.macro apicinterrupt3 num sym do_sym ENTRY(\sym) INTR_FRAME ASM_CLAC
@@ -1150,15 +1150,32 @@ ENTRY(\sym) END(\sym) .endm +#ifdef CONFIG_TRACING +#define trace(sym) trace_##sym +#define smp_trace(sym) smp_trace_##sym + +.macro trace_apicinterrupt num sym +apicinterrupt3 \num trace(\sym) smp_trace(\sym) +.endm +#else +.macro trace_apicinterrupt num sym do_sym +.endm +#endif + +.macro apicinterrupt num sym do_sym +apicinterrupt3 \num \sym \do_sym +trace_apicinterrupt \num \sym +.endm + #ifdef CONFIG_SMP -apicinterrupt IRQ_MOVE_CLEANUP_VECTOR \ +apicinterrupt3 IRQ_MOVE_CLEANUP_VECTOR \ irq_move_cleanup_interrupt smp_irq_move_cleanup_interrupt -apicinterrupt REBOOT_VECTOR \ +apicinterrupt3 REBOOT_VECTOR \ reboot_interrupt smp_reboot_interrupt #endif #ifdef CONFIG_X86_UV -apicinterrupt UV_BAU_MESSAGE \ +apicinterrupt3 UV_BAU_MESSAGE \ uv_bau_message_intr1 uv_bau_message_interrupt #endif apicinterrupt LOCAL_TIMER_VECTOR \
@@ -1167,14 +1184,19 @@ apicinterrupt X86_PLATFORM_IPI_VECTOR \ x86_platform_ipi smp_x86_platform_ipi #ifdef CONFIG_HAVE_KVM -apicinterrupt POSTED_INTR_VECTOR \ +apicinterrupt3 POSTED_INTR_VECTOR \ kvm_posted_intr_ipi smp_kvm_posted_intr_ipi #endif +#ifdef CONFIG_X86_MCE_THRESHOLD apicinterrupt THRESHOLD_APIC_VECTOR \ threshold_interrupt smp_threshold_interrupt +#endif + +#ifdef CONFIG_X86_THERMAL_VECTOR apicinterrupt THERMAL_APIC_VECTOR \ thermal_interrupt smp_thermal_interrupt +#endif #ifdef CONFIG_SMP apicinterrupt CALL_FUNCTION_SINGLE_VECTOR \
@@ -1451,13 +1473,13 @@ ENTRY(xen_failsafe_callback) CFI_ENDPROC END(xen_failsafe_callback) -apicinterrupt HYPERVISOR_CALLBACK_VECTOR \ +apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \ xen_hvm_callback_vector xen_evtchn_do_upcall #endif /* CONFIG_XEN */ #if IS_ENABLED(CONFIG_HYPERV) -apicinterrupt HYPERVISOR_CALLBACK_VECTOR \ +apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \ hyperv_callback_vector hyperv_vector_handler #endif /* CONFIG_HYPERV */
arch/x86/kernel/head_64.S +7 -1
@@ -518,9 +518,15 @@ ENTRY(idt_table) .skip IDT_ENTRIES * 16 .align L1_CACHE_BYTES -ENTRY(nmi_idt_table) +ENTRY(debug_idt_table) .skip IDT_ENTRIES * 16 +#ifdef CONFIG_TRACING + .align L1_CACHE_BYTES +ENTRY(trace_idt_table) + .skip IDT_ENTRIES * 16 +#endif + __PAGE_ALIGNED_BSS NEXT_PAGE(empty_zero_page) .skip PAGE_SIZE
arch/x86/kernel/irq.c +23 -10
@@ -18,6 +18,9 @@#include <asm/mce.h> #include <asm/hw_irq.h> +#define CREATE_TRACE_POINTS +#include <asm/trace/irq_vectors.h> +atomic_t irq_err_count;/* Function pointer for generic interrupt vector handling */
@@ -204,23 +207,21 @@ unsigned int __irq_entry do_IRQ(struct pt_regs *regs)/* * Handler for X86_PLATFORM_IPI_VECTOR. */ -void smp_x86_platform_ipi (struct pt_regs *regs) +void __smp_x86_platform_ipi (void ) { -struct pt_regs *old_regs =set_irq_regs (regs); - -ack_APIC_irq (); - -irq_enter (); - -exit_idle (); -inc_irq_stat (x86_platform_ipis);if (x86_platform_ipi_callback)x86_platform_ipi_callback (); +} -irq_exit (); +void smp_x86_platform_ipi (struct pt_regs *regs) +{ +struct pt_regs *old_regs =set_irq_regs (regs); +entering_ack_irq (); +__smp_x86_platform_ipi (); +exiting_irq ();set_irq_regs (old_regs); }
@@ -246,6 +247,18 @@ void smp_kvm_posted_intr_ipi(struct pt_regs *regs) }#endif +void smp_trace_x86_platform_ipi (struct pt_regs *regs) +{ +struct pt_regs *old_regs =set_irq_regs (regs); + +entering_ack_irq (); +trace_x86_platform_ipi_entry (X86_PLATFORM_IPI_VECTOR ); +__smp_x86_platform_ipi (); +trace_x86_platform_ipi_exit (X86_PLATFORM_IPI_VECTOR ); +exiting_irq (); +set_irq_regs (old_regs); +} +EXPORT_SYMBOL_GPL (vector_used_by_percpu_irq);#ifdef CONFIG_HOTPLUG_CPU
arch/x86/kernel/irq_work.c +22 -2
@@ -8,14 +8,34 @@#include <linux/irq_work.h> #include <linux/hardirq.h> #include <asm/apic.h> +#include <asm/trace/irq_vectors.h> -void smp_irq_work_interrupt (struct pt_regs *regs) +static inline void irq_work_entering_irq (void ) {irq_enter ();ack_APIC_irq (); +} + +static inline void __smp_irq_work_interrupt (void ) +{inc_irq_stat (apic_irq_work_irqs);irq_work_run (); -irq_exit (); +} + +void smp_irq_work_interrupt (struct pt_regs *regs) +{ +irq_work_entering_irq (); +__smp_irq_work_interrupt (); +exiting_irq (); +} + +void smp_trace_irq_work_interrupt (struct pt_regs *regs) +{ +irq_work_entering_irq (); +trace_irq_work_entry (IRQ_WORK_VECTOR ); +__smp_irq_work_interrupt (); +trace_irq_work_exit (IRQ_WORK_VECTOR ); +exiting_irq (); }void arch_irq_work_raise (void )
arch/x86/kernel/smp.c +57 -8
95 lines not on this page · raw message
arch/x86/kernel/tracepoint.c new file +61 -0
61 lines not on this page · raw message
arch/x86/kernel/traps.c +1 -1
@@ -785,7 +785,7 @@ void __init trap_init(void) x86_init.irqs.trap_init ();#ifdef CONFIG_X86_64 -memcpy (&nmi_idt_table, &idt_table,IDT_ENTRIES *16 ); +memcpy (&debug_idt_table, &idt_table,IDT_ENTRIES *16 );set_nmi_gate (X86_TRAP_DB , &debug);set_nmi_gate (X86_TRAP_BP , &int3);#endif
include/linux/tracepoint.h +2 -0
@@ -378,6 +378,8 @@ static inline void tracepoint_synchronize_unregister(void)#define DECLARE_EVENT_CLASS (name, proto, args, tstruct, assign, print)#define DEFINE_EVENT (template, name, proto, args) \ DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) +#define DEFINE_EVENT_FN (template, name, proto, args, reg, unreg)\ + DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))#define DEFINE_EVENT_PRINT (template, name, proto, args, print) \ DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) #define DEFINE_EVENT_CONDITION(template, name, proto, \
include/trace/define_trace.h +5 -0
@@ -44,6 +44,10 @@#define DEFINE_EVENT (template, name, proto, args) \ DEFINE_TRACE(name) +#undef DEFINE_EVENT_FN +#define DEFINE_EVENT_FN (template, name, proto, args, reg, unreg) \ + DEFINE_TRACE_FN(name, reg, unreg) +#undef DEFINE_EVENT_PRINT#define DEFINE_EVENT_PRINT (template, name, proto, args, print) \ DEFINE_TRACE(name)
@@ -91,6 +95,7 @@#undef TRACE_EVENT_CONDITION#undef DECLARE_EVENT_CLASS#undef DEFINE_EVENT +#undef DEFINE_EVENT_FN#undef DEFINE_EVENT_PRINT#undef DEFINE_EVENT_CONDITION#undef TRACE_HEADER_MULTI_READ
include/trace/ftrace.h +4 -0
@@ -71,6 +71,10 @@ static struct ftrace_event_call __used \ __attribute__((__aligned__(4))) event_##name +#undef DEFINE_EVENT_FN +#define DEFINE_EVENT_FN (template, name, proto, args, reg, unreg) \ + DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) +#undef DEFINE_EVENT_PRINT#define DEFINE_EVENT_PRINT (template, name, proto, args, print) \ DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
include/xen/events.h +3 -0
@@ -76,6 +76,9 @@ unsigned irq_from_evtchn(unsigned int evtchn);/* Xen HVM evtchn vector callback */ void xen_hvm_callback_vector (void ); +#ifdef CONFIG_TRACING +#define trace_xen_hvm_callback_vector xen_hvm_callback_vector +#endif extern int xen_have_vector_callback;int xen_set_callback_via (uint64_t via);void xen_evtchn_do_upcall (struct pt_regs *regs);