[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


 


Rackspace

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