[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 4 of 4] Add a trace hypercall to allow tracing from dom0 or domU
# HG changeset patch # User Olaf Hering <olaf@xxxxxxxxx> # Date 1310744207 -7200 # Node ID f72dcd1b8bbdc7487d58702058983a5aa812a74e # Parent 6e4aef7b5051e18f19f2367a4439bba8f495335c Add a trace hypercall to allow tracing from dom0 or domU. Mixing tracedata from Xen and dom0/domU events will help with debugging some issues. Either the chain of events is nice to know, or there is no console output available. Signed-off-by: Olaf Hering <olaf@xxxxxxxxx> diff -r 6e4aef7b5051 -r f72dcd1b8bbd tools/libxc/xc_tbuf.c --- a/tools/libxc/xc_tbuf.c +++ b/tools/libxc/xc_tbuf.c @@ -156,3 +156,49 @@ int xc_tbuf_set_evt_mask(xc_interface *x return do_sysctl(xch, &sysctl); } +static void do_tbuf_trace(xc_interface *xch, xen_guest_xentrace_t *t_guest) +{ + DECLARE_HYPERCALL; + DECLARE_HYPERCALL_BOUNCE(t_guest, sizeof(*t_guest), XC_HYPERCALL_BUFFER_BOUNCE_IN); + + if ( xc_hypercall_bounce_pre(xch, t_guest) ) + { + PERROR("Could not bounce buffer for xentrace hypercall"); + return; + } + + hypercall.op = __HYPERVISOR_xentrace_op; + hypercall.arg[0] = HYPERCALL_BUFFER_AS_ARG(t_guest); + if ( do_xen_hypercall(xch, &hypercall) < 0 ) + { + if ( errno == EACCES ) + DPRINTF("sysctl operation failed -- need to" + " rebuild the user-space tool set?\n"); + } + xc_hypercall_bounce_post(xch, t_guest); +} + +void xc_tbuf_trace(xc_interface *xch, uint16_t event, void *extra, size_t extra_bytes) +{ + DECLARE_HYPERCALL_BUFFER(xen_guest_xentrace_t, t_guest); + + t_guest = xc_hypercall_buffer_alloc(xch, t_guest, sizeof(xen_guest_xentrace_t)); + if ( !t_guest ) + { + PERROR("Could not allocate memory for xentrace hypercall"); + return ; + } + + t_guest->event = event; + if ( extra_bytes ) + { + if ( extra_bytes > sizeof(t_guest->extra) ) + extra_bytes = sizeof(t_guest->extra); + memcpy(t_guest->extra, extra, extra_bytes); + } + t_guest->extra_bytes = extra_bytes; + + do_tbuf_trace(xch, t_guest); + + xc_hypercall_buffer_free(xch, t_guest); +} diff -r 6e4aef7b5051 -r f72dcd1b8bbd tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -1269,6 +1269,8 @@ int xc_tbuf_set_cpu_mask(xc_interface *x int xc_tbuf_set_evt_mask(xc_interface *xch, uint32_t mask); +void xc_tbuf_trace(xc_interface *xch, uint16_t event, void *extra, size_t extra_bytes); + int xc_domctl(xc_interface *xch, struct xen_domctl *domctl); int xc_sysctl(xc_interface *xch, struct xen_sysctl *sysctl); diff -r 6e4aef7b5051 -r f72dcd1b8bbd xen/arch/x86/trace.c --- a/xen/arch/x86/trace.c +++ b/xen/arch/x86/trace.c @@ -15,6 +15,9 @@ asmlinkage void trace_hypercall(void) { struct cpu_user_regs *regs = guest_cpu_user_regs(); + if ( regs->eax == __HYPERVISOR_xentrace_op ) + return; + #ifdef __x86_64__ if ( is_pv_32on64_vcpu(current) ) { diff -r 6e4aef7b5051 -r f72dcd1b8bbd xen/arch/x86/x86_32/entry.S --- a/xen/arch/x86/x86_32/entry.S +++ b/xen/arch/x86/x86_32/entry.S @@ -699,6 +699,7 @@ ENTRY(hypercall_table) .long do_domctl .long do_kexec_op .long do_tmem_op + .long do_xentrace_op .rept __HYPERVISOR_arch_0-((.-hypercall_table)/4) .long do_ni_hypercall .endr @@ -747,6 +748,7 @@ ENTRY(hypercall_args_table) .byte 1 /* do_domctl */ .byte 2 /* do_kexec_op */ .byte 1 /* do_tmem_op */ + .byte 0 /* do_xentrace_op */ .rept __HYPERVISOR_arch_0-(.-hypercall_args_table) .byte 0 /* do_ni_hypercall */ .endr diff -r 6e4aef7b5051 -r f72dcd1b8bbd xen/arch/x86/x86_64/entry.S --- a/xen/arch/x86/x86_64/entry.S +++ b/xen/arch/x86/x86_64/entry.S @@ -694,6 +694,7 @@ ENTRY(hypercall_table) .quad do_domctl .quad do_kexec_op .quad do_tmem_op + .quad do_xentrace_op .rept __HYPERVISOR_arch_0-((.-hypercall_table)/8) .quad do_ni_hypercall .endr @@ -742,6 +743,7 @@ ENTRY(hypercall_args_table) .byte 1 /* do_domctl */ .byte 2 /* do_kexec */ .byte 1 /* do_tmem_op */ + .byte 0 /* do_xentrace_op */ .rept __HYPERVISOR_arch_0-(.-hypercall_args_table) .byte 0 /* do_ni_hypercall */ .endr diff -r 6e4aef7b5051 -r f72dcd1b8bbd xen/common/trace.c --- a/xen/common/trace.c +++ b/xen/common/trace.c @@ -31,6 +31,7 @@ #include <xen/percpu.h> #include <xen/pfn.h> #include <xen/cpu.h> +#include <xen/guest_access.h> #include <asm/atomic.h> #include <public/sysctl.h> @@ -806,6 +807,21 @@ unlock: tasklet_schedule(&trace_notify_dom0_tasklet); } +void do_xentrace_op(XEN_GUEST_HANDLE(xen_guest_xentrace_t) u_xentrace) +{ + xen_guest_xentrace_t tr; + + if ( copy_from_guest(&tr, u_xentrace, 1 ) ) + return; + if ( tr.event & ~((1u<<TRC_SUBCLS_SHIFT)-1) ) + return; + + if ( tr.extra_bytes > sizeof(tr.extra) ) + tr.extra_bytes = sizeof(tr.extra); + + __trace_var(tr.event | TRC_GUEST, 1, tr.extra_bytes, tr.extra); +} + /* * Local variables: * mode: C diff -r 6e4aef7b5051 -r f72dcd1b8bbd xen/include/public/trace.h --- a/xen/include/public/trace.h +++ b/xen/include/public/trace.h @@ -26,6 +26,8 @@ #ifndef __XEN_PUBLIC_TRACE_H__ #define __XEN_PUBLIC_TRACE_H__ +#include "xen.h" + #define TRACE_EXTRA_MAX 7 #define TRACE_EXTRA_SHIFT 28 @@ -65,6 +67,7 @@ #define TRC_LOST_RECORDS (TRC_GEN + 1) #define TRC_TRACE_WRAP_BUFFER (TRC_GEN + 2) #define TRC_TRACE_CPU_CHANGE (TRC_GEN + 3) +#define TRC_TRACE_GUEST_HYPERCALL (TRC_GEN + 4) #define TRC_SCHED_RUNSTATE_CHANGE (TRC_SCHED_MIN + 1) #define TRC_SCHED_CONTINUE_RUNNING (TRC_SCHED_MIN + 2) @@ -200,6 +203,13 @@ struct t_rec { } u; }; +struct xen_guest_xentrace { + uint16_t event, extra_bytes; + uint8_t extra[TRACE_EXTRA_MAX * sizeof(uint32_t)]; +}; +typedef struct xen_guest_xentrace xen_guest_xentrace_t; +DEFINE_XEN_GUEST_HANDLE(xen_guest_xentrace_t); + /* * This structure contains the metadata for a single trace buffer. The head * field, indexes into an array of struct t_rec's. diff -r 6e4aef7b5051 -r f72dcd1b8bbd xen/include/public/xen.h --- a/xen/include/public/xen.h +++ b/xen/include/public/xen.h @@ -94,6 +94,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_pfn_t); #define __HYPERVISOR_kexec_op 37 #define __HYPERVISOR_tmem_op 38 #define __HYPERVISOR_xc_reserved_op 39 /* reserved for XenClient */ +#define __HYPERVISOR_xentrace_op 40 /* Architecture-specific hypercall definitions. */ #define __HYPERVISOR_arch_0 48 diff -r 6e4aef7b5051 -r f72dcd1b8bbd xen/include/xen/hypercall.h --- a/xen/include/xen/hypercall.h +++ b/xen/include/xen/hypercall.h @@ -14,6 +14,7 @@ #include <public/platform.h> #include <public/event_channel.h> #include <public/tmem.h> +#include <public/trace.h> #include <asm/hypercall.h> #include <xsm/xsm.h> @@ -43,6 +44,10 @@ extern long do_platform_op( XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op); +extern void +do_xentrace_op( + XEN_GUEST_HANDLE(xen_guest_xentrace_t) u_xentrace); + /* * To allow safe resume of do_memory_op() after preemption, we need to know * at what point in the page list to resume. For this purpose I steal the _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |