# 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
|