direct-io.hg
changeset 15235:a7601de2f733
Add backtrace support to xenoprof.
Signed-off-by: Amitabha Roy <amitabha.roy@gmail.com>
Reviewed-by: Jose Renato G Santos <joserenato.santos@hp.com>
Signed-off-by: Amitabha Roy <amitabha.roy@gmail.com>
Reviewed-by: Jose Renato G Santos <joserenato.santos@hp.com>
author | kfraser@localhost.localdomain |
---|---|
date | Thu Jun 07 14:30:21 2007 +0100 (2007-06-07) |
parents | 1cae82505e9e |
children | 56bab6f498ac |
files | xen/Rules.mk xen/arch/ia64/xen/oprofile/perfmon.c xen/arch/x86/oprofile/Makefile xen/arch/x86/oprofile/backtrace.c xen/arch/x86/oprofile/op_model_athlon.c xen/arch/x86/oprofile/op_model_p4.c xen/arch/x86/oprofile/op_model_ppro.c xen/arch/x86/traps.c xen/common/xenoprof.c xen/include/asm-ia64/xenoprof.h xen/include/asm-x86/xenoprof.h xen/include/public/xenoprof.h xen/include/xen/xenoprof.h |
line diff
1.1 --- a/xen/Rules.mk Thu Jun 07 11:15:24 2007 +0100 1.2 +++ b/xen/Rules.mk Thu Jun 07 14:30:21 2007 +0100 1.3 @@ -3,10 +3,11 @@ 1.4 # If you change any of these configuration options then you must 1.5 # 'make clean' before rebuilding. 1.6 # 1.7 -verbose ?= n 1.8 -perfc ?= n 1.9 -perfc_arrays?= n 1.10 -crash_debug ?= n 1.11 +verbose ?= n 1.12 +perfc ?= n 1.13 +perfc_arrays ?= n 1.14 +crash_debug ?= n 1.15 +frame_pointer ?= n 1.16 1.17 XEN_ROOT=$(BASEDIR)/.. 1.18 include $(XEN_ROOT)/Config.mk 1.19 @@ -14,11 +15,15 @@ include $(XEN_ROOT)/Config.mk 1.20 # Hardcoded configuration implications and dependencies. 1.21 # Do this is a neater way if it becomes unwieldy. 1.22 ifeq ($(debug),y) 1.23 -verbose := y 1.24 +verbose := y 1.25 +frame_pointer := y 1.26 endif 1.27 ifeq ($(perfc_arrays),y) 1.28 perfc := y 1.29 endif 1.30 +ifeq ($(frame_pointer),y) 1.31 +CFLAGS := $(shell echo $(CFLAGS) | sed -e 's/-f[^ ]*omit-frame-pointer//g') 1.32 +endif 1.33 1.34 # Set ARCH/SUBARCH appropriately. 1.35 override COMPILE_SUBARCH := $(XEN_COMPILE_ARCH) 1.36 @@ -50,18 +55,19 @@ ALL_OBJS-y += $(BASEDIR)/d 1.37 ALL_OBJS-$(ACM_SECURITY) += $(BASEDIR)/acm/built_in.o 1.38 ALL_OBJS-y += $(BASEDIR)/arch/$(TARGET_ARCH)/built_in.o 1.39 1.40 -CFLAGS-y += -g -D__XEN__ 1.41 -CFLAGS-$(ACM_SECURITY) += -DACM_SECURITY 1.42 -CFLAGS-$(verbose) += -DVERBOSE 1.43 -CFLAGS-$(crash_debug) += -DCRASH_DEBUG 1.44 -CFLAGS-$(perfc) += -DPERF_COUNTERS 1.45 -CFLAGS-$(perfc_arrays) += -DPERF_ARRAYS 1.46 +CFLAGS-y += -g -D__XEN__ 1.47 +CFLAGS-$(ACM_SECURITY) += -DACM_SECURITY 1.48 +CFLAGS-$(verbose) += -DVERBOSE 1.49 +CFLAGS-$(crash_debug) += -DCRASH_DEBUG 1.50 +CFLAGS-$(perfc) += -DPERF_COUNTERS 1.51 +CFLAGS-$(perfc_arrays) += -DPERF_ARRAYS 1.52 +CFLAGS-$(frame_pointer) += -fno-omit-frame-pointer -DCONFIG_FRAME_POINTER 1.53 1.54 ifneq ($(max_phys_cpus),) 1.55 -CFLAGS-y += -DMAX_PHYS_CPUS=$(max_phys_cpus) 1.56 +CFLAGS-y += -DMAX_PHYS_CPUS=$(max_phys_cpus) 1.57 endif 1.58 1.59 -AFLAGS-y += -D__ASSEMBLY__ 1.60 +AFLAGS-y += -D__ASSEMBLY__ 1.61 1.62 ALL_OBJS := $(ALL_OBJS-y) 1.63
2.1 --- a/xen/arch/ia64/xen/oprofile/perfmon.c Thu Jun 07 11:15:24 2007 +0100 2.2 +++ b/xen/arch/ia64/xen/oprofile/perfmon.c Thu Jun 07 14:30:21 2007 +0100 2.3 @@ -37,7 +37,7 @@ 2.4 #include <asm/ptrace.h> 2.5 2.6 // XXX move them to an appropriate header file 2.7 -extern void xenoprof_log_event(struct vcpu *vcpu, 2.8 +extern void xenoprof_log_event(struct vcpu *vcpu, struct pt_regs * regs, 2.9 unsigned long eip, int mode, int event); 2.10 extern int is_active(struct domain *d); 2.11 2.12 @@ -55,7 +55,10 @@ xenoprof_handler(struct task_struct *tas 2.13 if (!allow_virq || !allow_ints) 2.14 return 0; 2.15 2.16 - xenoprof_log_event(current, ip, xenoprofile_get_mode(task, regs), event); 2.17 + // Note that log event actually expect cpu_user_regs, cast back 2.18 + // appropriately when doing the backtrace implementation in ia64 2.19 + xenoprof_log_event(current, regs, ip, xenoprofile_get_mode(task, regs), 2.20 + event); 2.21 2.22 // send VIRQ_XENOPROF 2.23 if (is_active(current->domain) && !ring_0(regs))
3.1 --- a/xen/arch/x86/oprofile/Makefile Thu Jun 07 11:15:24 2007 +0100 3.2 +++ b/xen/arch/x86/oprofile/Makefile Thu Jun 07 14:30:21 2007 +0100 3.3 @@ -3,3 +3,4 @@ obj-y += nmi_int.o 3.4 obj-y += op_model_p4.o 3.5 obj-y += op_model_ppro.o 3.6 obj-y += op_model_athlon.o 3.7 +obj-y += backtrace.o
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/xen/arch/x86/oprofile/backtrace.c Thu Jun 07 14:30:21 2007 +0100 4.3 @@ -0,0 +1,132 @@ 4.4 +/** 4.5 + * @file backtrace.c 4.6 + * 4.7 + * @remark Copyright 2002 OProfile authors 4.8 + * @remark Read the file COPYING 4.9 + * 4.10 + * @author John Levon 4.11 + * @author David Smith 4.12 + * Modified for Xen by Amitabha Roy 4.13 + * 4.14 + */ 4.15 + 4.16 +#include<xen/types.h> 4.17 +#include<asm/page.h> 4.18 +#include<xen/xenoprof.h> 4.19 +#include<asm/guest_access.h> 4.20 + 4.21 +struct frame_head { 4.22 + struct frame_head * ebp; 4.23 + unsigned long ret; 4.24 +} __attribute__((packed)); 4.25 + 4.26 +static struct frame_head * 4.27 +dump_hypervisor_backtrace(struct domain *d, struct vcpu *vcpu, 4.28 + struct frame_head * head, int mode) 4.29 +{ 4.30 + if (!xenoprof_add_trace(d, vcpu, head->ret, mode)) 4.31 + return 0; 4.32 + 4.33 + /* frame pointers should strictly progress back up the stack 4.34 + * (towards higher addresses) */ 4.35 + if (head >= head->ebp) 4.36 + return NULL; 4.37 + 4.38 + return head->ebp; 4.39 +} 4.40 + 4.41 +static struct frame_head * 4.42 +dump_guest_backtrace(struct domain *d, struct vcpu *vcpu, 4.43 + struct frame_head * head, int mode) 4.44 +{ 4.45 + struct frame_head bufhead[2]; 4.46 + XEN_GUEST_HANDLE(char) guest_head = guest_handle_from_ptr(head, char); 4.47 + 4.48 + /* Also check accessibility of one struct frame_head beyond */ 4.49 + if (!guest_handle_okay(guest_head, sizeof(bufhead))) 4.50 + return 0; 4.51 + if (__copy_from_guest_offset((char *)bufhead, guest_head, 0, 4.52 + sizeof(bufhead))) 4.53 + return 0; 4.54 + 4.55 + if (!xenoprof_add_trace(d, vcpu, bufhead[0].ret, mode)) 4.56 + return 0; 4.57 + 4.58 + /* frame pointers should strictly progress back up the stack 4.59 + * (towards higher addresses) */ 4.60 + if (head >= bufhead[0].ebp) 4.61 + return NULL; 4.62 + 4.63 + return bufhead[0].ebp; 4.64 +} 4.65 + 4.66 +/* 4.67 + * | | /\ Higher addresses 4.68 + * | | 4.69 + * --------------- stack base (address of current_thread_info) 4.70 + * | thread info | 4.71 + * . . 4.72 + * | stack | 4.73 + * --------------- saved regs->ebp value if valid (frame_head address) 4.74 + * . . 4.75 + * --------------- saved regs->rsp value if x86_64 4.76 + * | | 4.77 + * --------------- struct pt_regs * stored on stack if 32-bit 4.78 + * | | 4.79 + * . . 4.80 + * | | 4.81 + * --------------- %esp 4.82 + * | | 4.83 + * | | \/ Lower addresses 4.84 + * 4.85 + * Thus, regs (or regs->rsp for x86_64) <-> stack base restricts the 4.86 + * valid(ish) ebp values. Note: (1) for x86_64, NMI and several other 4.87 + * exceptions use special stacks, maintained by the interrupt stack table 4.88 + * (IST). These stacks are set up in trap_init() in 4.89 + * arch/x86_64/kernel/traps.c. Thus, for x86_64, regs now does not point 4.90 + * to the kernel stack; instead, it points to some location on the NMI 4.91 + * stack. On the other hand, regs->rsp is the stack pointer saved when the 4.92 + * NMI occurred. (2) For 32-bit, regs->esp is not valid because the 4.93 + * processor does not save %esp on the kernel stack when interrupts occur 4.94 + * in the kernel mode. 4.95 + */ 4.96 +#if defined(CONFIG_FRAME_POINTER) 4.97 +static int valid_hypervisor_stack(struct frame_head * head, 4.98 + struct cpu_user_regs * regs) 4.99 +{ 4.100 + unsigned long headaddr = (unsigned long)head; 4.101 +#ifdef CONFIG_X86_64 4.102 + unsigned long stack = (unsigned long)regs->rsp; 4.103 +#else 4.104 + unsigned long stack = (unsigned long)regs; 4.105 +#endif 4.106 + unsigned long stack_base = (stack & ~(STACK_SIZE - 1)) + STACK_SIZE; 4.107 + 4.108 + return headaddr > stack && headaddr < stack_base; 4.109 +} 4.110 +#else 4.111 +/* without fp, it's just junk */ 4.112 +static int valid_hypervisor_stack(struct frame_head * head, 4.113 + struct cpu_user_regs * regs) 4.114 +{ 4.115 + return 0; 4.116 +} 4.117 +#endif 4.118 + 4.119 +void xenoprof_backtrace(struct domain *d, struct vcpu *vcpu, 4.120 + struct cpu_user_regs * const regs, 4.121 + unsigned long depth, int mode) 4.122 +{ 4.123 + struct frame_head *head; 4.124 + 4.125 + head = (struct frame_head *)regs->ebp; 4.126 + 4.127 + if (mode > 1) { 4.128 + while (depth-- && valid_hypervisor_stack(head, regs)) 4.129 + head = dump_hypervisor_backtrace(d, vcpu, head, mode); 4.130 + return; 4.131 + } 4.132 + 4.133 + while (depth-- && head) 4.134 + head = dump_guest_backtrace(d, vcpu, head, mode); 4.135 +}
5.1 --- a/xen/arch/x86/oprofile/op_model_athlon.c Thu Jun 07 11:15:24 2007 +0100 5.2 +++ b/xen/arch/x86/oprofile/op_model_athlon.c Thu Jun 07 14:30:21 2007 +0100 5.3 @@ -43,8 +43,8 @@ 5.4 5.5 static unsigned long reset_value[NUM_COUNTERS]; 5.6 5.7 -extern void xenoprof_log_event(struct vcpu *v, unsigned long eip, 5.8 - int mode, int event); 5.9 +extern void xenoprof_log_event(struct vcpu *v, struct cpu_user_regs * regs, 5.10 + unsigned long eip, int mode, int event); 5.11 extern int xenoprofile_get_mode(struct vcpu *v, 5.12 struct cpu_user_regs * const regs); 5.13 5.14 @@ -130,7 +130,7 @@ static int athlon_check_ctrs(unsigned in 5.15 for (i = 0 ; i < NUM_COUNTERS; ++i) { 5.16 CTR_READ(low, high, msrs, i); 5.17 if (CTR_OVERFLOWED(low)) { 5.18 - xenoprof_log_event(current, eip, mode, i); 5.19 + xenoprof_log_event(current, regs, eip, mode, i); 5.20 CTR_WRITE(reset_value[i], msrs, i); 5.21 ovf = 1; 5.22 }
6.1 --- a/xen/arch/x86/oprofile/op_model_p4.c Thu Jun 07 11:15:24 2007 +0100 6.2 +++ b/xen/arch/x86/oprofile/op_model_p4.c Thu Jun 07 14:30:21 2007 +0100 6.3 @@ -620,8 +620,8 @@ static void p4_setup_ctrs(struct op_msrs 6.4 } 6.5 } 6.6 6.7 -extern void xenoprof_log_event(struct vcpu *v, unsigned long eip, 6.8 - int mode, int event); 6.9 +extern void xenoprof_log_event(struct vcpu *v, struct cpu_user_regs * regs, 6.10 + unsigned long eip, int mode, int event); 6.11 extern int xenoprofile_get_mode(struct vcpu *v, 6.12 struct cpu_user_regs * const regs); 6.13 6.14 @@ -664,8 +664,8 @@ static int p4_check_ctrs(unsigned int co 6.15 CCCR_READ(low, high, real); 6.16 CTR_READ(ctr, high, real); 6.17 if (CCCR_OVF_P(low) || CTR_OVERFLOW_P(ctr)) { 6.18 - xenoprof_log_event(current, eip, mode, i); 6.19 - CTR_WRITE(reset_value[i], real); 6.20 + xenoprof_log_event(current, regs, eip, mode, i); 6.21 + CTR_WRITE(reset_value[i], real); 6.22 CCCR_CLEAR_OVF(low); 6.23 CCCR_WRITE(low, high, real); 6.24 CTR_WRITE(reset_value[i], real);
7.1 --- a/xen/arch/x86/oprofile/op_model_ppro.c Thu Jun 07 11:15:24 2007 +0100 7.2 +++ b/xen/arch/x86/oprofile/op_model_ppro.c Thu Jun 07 14:30:21 2007 +0100 7.3 @@ -88,8 +88,8 @@ static void ppro_setup_ctrs(struct op_ms 7.4 } 7.5 } 7.6 7.7 -extern void xenoprof_log_event(struct vcpu *v, unsigned long eip, 7.8 - int mode, int event); 7.9 +extern void xenoprof_log_event(struct vcpu *v, struct cpu_user_regs * regs, 7.10 + unsigned long eip, int mode, int event); 7.11 extern int xenoprofile_get_mode(struct vcpu *v, 7.12 struct cpu_user_regs * const regs); 7.13 7.14 @@ -106,7 +106,7 @@ static int ppro_check_ctrs(unsigned int 7.15 for (i = 0 ; i < NUM_COUNTERS; ++i) { 7.16 CTR_READ(low, high, msrs, i); 7.17 if (CTR_OVERFLOWED(low)) { 7.18 - xenoprof_log_event(current, eip, mode, i); 7.19 + xenoprof_log_event(current, regs, eip, mode, i); 7.20 CTR_WRITE(reset_value[i], msrs, i); 7.21 ovf = 1; 7.22 }
8.1 --- a/xen/arch/x86/traps.c Thu Jun 07 11:15:24 2007 +0100 8.2 +++ b/xen/arch/x86/traps.c Thu Jun 07 14:30:21 2007 +0100 8.3 @@ -167,7 +167,7 @@ static void show_guest_stack(struct cpu_ 8.4 printk("\n"); 8.5 } 8.6 8.7 -#ifdef NDEBUG 8.8 +#if !defined(CONFIG_FRAME_POINTER) 8.9 8.10 static void show_trace(struct cpu_user_regs *regs) 8.11 {
9.1 --- a/xen/common/xenoprof.c Thu Jun 07 11:15:24 2007 +0100 9.2 +++ b/xen/common/xenoprof.c Thu Jun 07 14:30:21 2007 +0100 9.3 @@ -31,6 +31,7 @@ unsigned int pdomains; 9.4 unsigned int activated; 9.5 struct domain *xenoprof_primary_profiler; 9.6 int xenoprof_state = XENOPROF_IDLE; 9.7 +static unsigned long backtrace_depth; 9.8 9.9 u64 total_samples; 9.10 u64 invalid_buffer_samples; 9.11 @@ -205,7 +206,8 @@ static int alloc_xenoprof_struct( 9.12 i = 0; 9.13 for_each_vcpu ( d, v ) 9.14 { 9.15 - xenoprof_buf_t *buf = (xenoprof_buf_t *)&d->xenoprof->rawbuf[i * bufsize]; 9.16 + xenoprof_buf_t *buf = (xenoprof_buf_t *) 9.17 + &d->xenoprof->rawbuf[i * bufsize]; 9.18 9.19 d->xenoprof->vcpu[v->vcpu_id].event_size = max_samples; 9.20 d->xenoprof->vcpu[v->vcpu_id].buffer = buf; 9.21 @@ -414,21 +416,82 @@ static int add_passive_list(XEN_GUEST_HA 9.22 return ret; 9.23 } 9.24 9.25 -void xenoprof_log_event( 9.26 - struct vcpu *vcpu, unsigned long eip, int mode, int event) 9.27 + 9.28 +/* Get space in the buffer */ 9.29 +static int xenoprof_buf_space(struct domain *d, xenoprof_buf_t * buf, int size) 9.30 +{ 9.31 + int head, tail; 9.32 + 9.33 + head = xenoprof_buf(d, buf, event_head); 9.34 + tail = xenoprof_buf(d, buf, event_tail); 9.35 + 9.36 + return ((tail > head) ? 0 : size) + tail - head - 1; 9.37 +} 9.38 + 9.39 +/* Check for space and add a sample. Return 1 if successful, 0 otherwise. */ 9.40 +static int xenoprof_add_sample(struct domain *d, xenoprof_buf_t *buf, 9.41 + unsigned long eip, int mode, int event) 9.42 +{ 9.43 + int head, tail, size; 9.44 + 9.45 + head = xenoprof_buf(d, buf, event_head); 9.46 + tail = xenoprof_buf(d, buf, event_tail); 9.47 + size = xenoprof_buf(d, buf, event_size); 9.48 + 9.49 + /* make sure indexes in shared buffer are sane */ 9.50 + if ( (head < 0) || (head >= size) || (tail < 0) || (tail >= size) ) 9.51 + { 9.52 + corrupted_buffer_samples++; 9.53 + return 0; 9.54 + } 9.55 + 9.56 + if ( xenoprof_buf_space(d, buf, size) > 0 ) 9.57 + { 9.58 + xenoprof_buf(d, buf, event_log[head].eip) = eip; 9.59 + xenoprof_buf(d, buf, event_log[head].mode) = mode; 9.60 + xenoprof_buf(d, buf, event_log[head].event) = event; 9.61 + head++; 9.62 + if ( head >= size ) 9.63 + head = 0; 9.64 + 9.65 + xenoprof_buf(d, buf, event_head) = head; 9.66 + } 9.67 + else 9.68 + { 9.69 + xenoprof_buf(d, buf, lost_samples)++; 9.70 + lost_samples++; 9.71 + return 0; 9.72 + } 9.73 + 9.74 + return 1; 9.75 +} 9.76 + 9.77 +int xenoprof_add_trace(struct domain *d, struct vcpu *vcpu, 9.78 + unsigned long eip, int mode) 9.79 +{ 9.80 + xenoprof_buf_t *buf = d->xenoprof->vcpu[vcpu->vcpu_id].buffer; 9.81 + 9.82 + /* Do not accidentally write an escape code due to a broken frame. */ 9.83 + if ( eip == XENOPROF_ESCAPE_CODE ) 9.84 + { 9.85 + invalid_buffer_samples++; 9.86 + return 0; 9.87 + } 9.88 + 9.89 + return xenoprof_add_sample(d, buf, eip, mode, 0); 9.90 +} 9.91 + 9.92 +void xenoprof_log_event(struct vcpu *vcpu, 9.93 + struct cpu_user_regs * regs, unsigned long eip, 9.94 + int mode, int event) 9.95 { 9.96 struct domain *d = vcpu->domain; 9.97 struct xenoprof_vcpu *v; 9.98 xenoprof_buf_t *buf; 9.99 - int head; 9.100 - int tail; 9.101 - int size; 9.102 - 9.103 9.104 total_samples++; 9.105 9.106 - /* ignore samples of un-monitored domains */ 9.107 - /* Count samples in idle separate from other unmonitored domains */ 9.108 + /* Ignore samples of un-monitored domains. */ 9.109 if ( !is_profiled(d) ) 9.110 { 9.111 others_samples++; 9.112 @@ -436,41 +499,29 @@ void xenoprof_log_event( 9.113 } 9.114 9.115 v = &d->xenoprof->vcpu[vcpu->vcpu_id]; 9.116 - 9.117 - /* Sanity check. Should never happen */ 9.118 if ( v->buffer == NULL ) 9.119 { 9.120 invalid_buffer_samples++; 9.121 return; 9.122 } 9.123 - 9.124 + 9.125 buf = v->buffer; 9.126 9.127 - head = xenoprof_buf(d, buf, event_head); 9.128 - tail = xenoprof_buf(d, buf, event_tail); 9.129 - size = v->event_size; 9.130 - 9.131 - /* make sure indexes in shared buffer are sane */ 9.132 - if ( (head < 0) || (head >= size) || (tail < 0) || (tail >= size) ) 9.133 + /* Provide backtrace if requested. */ 9.134 + if ( backtrace_depth > 0 ) 9.135 { 9.136 - corrupted_buffer_samples++; 9.137 - return; 9.138 + if ( (xenoprof_buf_space(d, buf, v->event_size) < 2) || 9.139 + !xenoprof_add_sample(d, buf, XENOPROF_ESCAPE_CODE, mode, 9.140 + XENOPROF_TRACE_BEGIN) ) 9.141 + { 9.142 + xenoprof_buf(d, buf, lost_samples)++; 9.143 + lost_samples++; 9.144 + return; 9.145 + } 9.146 } 9.147 9.148 - if ( (head == tail - 1) || (head == size - 1 && tail == 0) ) 9.149 - { 9.150 - xenoprof_buf(d, buf, lost_samples)++; 9.151 - lost_samples++; 9.152 - } 9.153 - else 9.154 + if ( xenoprof_add_sample(d, buf, eip, mode, event) ) 9.155 { 9.156 - xenoprof_buf(d, buf, event_log[head].eip) = eip; 9.157 - xenoprof_buf(d, buf, event_log[head].mode) = mode; 9.158 - xenoprof_buf(d, buf, event_log[head].event) = event; 9.159 - head++; 9.160 - if ( head >= size ) 9.161 - head = 0; 9.162 - xenoprof_buf(d, buf, event_head) = head; 9.163 if ( is_active(vcpu->domain) ) 9.164 active_samples++; 9.165 else 9.166 @@ -481,9 +532,15 @@ void xenoprof_log_event( 9.167 xenoprof_buf(d, buf, kernel_samples)++; 9.168 else 9.169 xenoprof_buf(d, buf, xen_samples)++; 9.170 + 9.171 } 9.172 + 9.173 + if ( backtrace_depth > 0 ) 9.174 + xenoprof_backtrace(d, vcpu, regs, backtrace_depth, mode); 9.175 } 9.176 9.177 + 9.178 + 9.179 static int xenoprof_op_init(XEN_GUEST_HANDLE(void) arg) 9.180 { 9.181 struct xenoprof_init xenoprof_init; 9.182 @@ -685,7 +742,8 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN 9.183 break; 9.184 9.185 case XENOPROF_stop: 9.186 - if ( xenoprof_state != XENOPROF_PROFILING ) { 9.187 + if ( xenoprof_state != XENOPROF_PROFILING ) 9.188 + { 9.189 ret = -EPERM; 9.190 break; 9.191 } 9.192 @@ -729,9 +787,18 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN 9.193 activated = 0; 9.194 adomains=0; 9.195 xenoprof_primary_profiler = NULL; 9.196 + backtrace_depth=0; 9.197 ret = 0; 9.198 } 9.199 break; 9.200 + 9.201 + case XENOPROF_set_backtrace: 9.202 + ret = 0; 9.203 + if ( !xenoprof_backtrace_supported() ) 9.204 + ret = -EINVAL; 9.205 + else if ( copy_from_guest(&backtrace_depth, arg, 1) ) 9.206 + ret = -EFAULT; 9.207 + break; 9.208 9.209 default: 9.210 ret = -ENOSYS;
10.1 --- a/xen/include/asm-ia64/xenoprof.h Thu Jun 07 11:15:24 2007 +0100 10.2 +++ b/xen/include/asm-ia64/xenoprof.h Thu Jun 07 14:30:21 2007 +0100 10.3 @@ -37,7 +37,17 @@ void xenoprof_arch_release_counters(void 10.4 struct vcpu; 10.5 struct cpu_user_regs; 10.6 int xenoprofile_get_mode(struct vcpu *v, struct cpu_user_regs * const regs); 10.7 - 10.8 +static inline int xenoprof_backtrace_supported(void) 10.9 +{ 10.10 + return 0; 10.11 +} 10.12 +static inline void xenoprof_backtrace( 10.13 + struct domain *d, struct vcpu *vcpu, 10.14 + struct pt_regs *const regs, unsigned long depth, int mode) 10.15 +{ 10.16 + /* To be implemented */ 10.17 + return; 10.18 +} 10.19 #define xenoprof_shared_gmfn(d, gmaddr, maddr) \ 10.20 assign_domain_page((d), (gmaddr), (maddr)); 10.21
11.1 --- a/xen/include/asm-x86/xenoprof.h Thu Jun 07 11:15:24 2007 +0100 11.2 +++ b/xen/include/asm-x86/xenoprof.h Thu Jun 07 14:30:21 2007 +0100 11.3 @@ -46,7 +46,18 @@ int xenoprof_arch_counter(XEN_GUEST_HAND 11.4 11.5 struct vcpu; 11.6 struct cpu_user_regs; 11.7 + 11.8 int xenoprofile_get_mode(struct vcpu *v, struct cpu_user_regs * const regs); 11.9 + 11.10 +static inline int xenoprof_backtrace_supported(void) 11.11 +{ 11.12 + return 1; 11.13 +} 11.14 + 11.15 +void xenoprof_backtrace( 11.16 + struct domain *d, struct vcpu *vcpu, 11.17 + struct cpu_user_regs *const regs, unsigned long depth, int mode); 11.18 + 11.19 #define xenoprof_shared_gmfn(d, gmaddr, maddr) \ 11.20 do { \ 11.21 (void)(maddr); \
12.1 --- a/xen/include/public/xenoprof.h Thu Jun 07 11:15:24 2007 +0100 12.2 +++ b/xen/include/public/xenoprof.h Thu Jun 07 14:30:21 2007 +0100 12.3 @@ -49,7 +49,8 @@ 12.4 #define XENOPROF_release_counters 12 12.5 #define XENOPROF_shutdown 13 12.6 #define XENOPROF_get_buffer 14 12.7 -#define XENOPROF_last_op 14 12.8 +#define XENOPROF_set_backtrace 15 12.9 +#define XENOPROF_last_op 15 12.10 12.11 #define MAX_OPROF_EVENTS 32 12.12 #define MAX_OPROF_DOMAINS 25 12.13 @@ -62,6 +63,11 @@ struct event_log { 12.14 uint8_t event; 12.15 }; 12.16 12.17 +/* PC value that indicates a special code */ 12.18 +#define XENOPROF_ESCAPE_CODE ~0UL 12.19 +/* Transient events for the xenoprof->oprofile cpu buf */ 12.20 +#define XENOPROF_TRACE_BEGIN 1 12.21 + 12.22 /* Xenoprof buffer shared between Xen and domain - 1 per VCPU */ 12.23 struct xenoprof_buf { 12.24 uint32_t event_head;
13.1 --- a/xen/include/xen/xenoprof.h Thu Jun 07 11:15:24 2007 +0100 13.2 +++ b/xen/include/xen/xenoprof.h Thu Jun 07 14:30:21 2007 +0100 13.3 @@ -66,6 +66,8 @@ struct domain; 13.4 void free_xenoprof_pages(struct domain *d); 13.5 13.6 int do_xenoprof_op(int op, XEN_GUEST_HANDLE(void) arg); 13.7 +int xenoprof_add_trace(struct domain *d, struct vcpu *v, 13.8 + unsigned long eip, int mode); 13.9 13.10 extern struct domain *xenoprof_primary_profiler; 13.11