diff options
author | George Dunlap <george.dunlap@eu.citrix.com> | 2012-03-07 10:58:25 +0000 |
---|---|---|
committer | George Dunlap <george.dunlap@eu.citrix.com> | 2012-03-07 10:58:25 +0000 |
commit | 11d7e56fff6dd5305d71216a684d74f20d77cc1a (patch) | |
tree | 05df8dea07590d256f644d330a06df524d275baa | |
parent | 19de40af1abe3606632ed115af9d82b326fe97bb (diff) | |
download | xen-11d7e56fff6dd5305d71216a684d74f20d77cc1a.tar.gz xen-11d7e56fff6dd5305d71216a684d74f20d77cc1a.tar.bz2 xen-11d7e56fff6dd5305d71216a684d74f20d77cc1a.zip |
xenoprof: Adjust indentation
Bring indentation into Xen hypervisor standard coding style.
No functional changes.
Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
Committed-by: Keir Fraser <keir@xen.org>
xen-unstable changeset: 24536:212cf37d50e1
xen-unstable date: Mon Jan 23 09:36:01 2012 +0000
xenoprof: Handle 32-bit guest stacks properly in a 64-bit hypervisor
The dump_guest_backtrace() function attempted to walk the stack
based on the assumption that the guest and hypervisor pointer sizes
were the same; thus any 32-bit guest running under 64-bit hypervisor
would have unreliable results.
In 64-bit mode, read the 32-bit stack frame properly.
Signed-off-by: Marcus Granado <marcus.granado@eu.citrix.com>
Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
Committed-by: Keir Fraser <keir@xen.org>
xen-unstable changeset: 24537:3c0a533d3af0
xen-unstable date: Mon Jan 23 09:36:29 2012 +0000
xenoprof: Use uint64_t explicitly for internal calls
A recent changeset to make XENOPROF_ESCAPE_CODE consistent across
32- and 64-bit builds caused a build failure, because values were
passed through functions as "unsigned long". Replace these with
uint64_t explicitly.
Also remove redundant function prototype from perfmon.c, now that
it's in a header file.
Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
Committed-by: Keir Fraser <keir@xen.org>
xen-unstable changeset: 24564:768c932ea8da
xen-unstable date: Thu Jan 26 11:03:23 2012 +0000
xenoprof: Make the escape code consistent across 32 and 64-bit xen
At the moment, the xenoprof escape code is defined as "~0UL".
Unfortunately, this expands to 0xffffffff on 32-bit systems
and 0xffffffffffffffff on 64-bit systems; with the result that
while 32-on-32 and 64-in-64 work fine, 32-on-64 (also known as
"compat mode") is broken.
This patch makes the definition consistent across architectures.
In so doing, it will break old-32-bit-on-new-Xen, and vice versa;
but this was seen as an acceptable thing to do.
Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com>
Committed-by: Keir Fraser <keir@xen.org>
xen-unstable changeset: 24565:1e27e827e6a8
xen-unstable date: Thu Jan 26 11:03:50 2012 +0000
-rw-r--r-- | xen/arch/ia64/xen/oprofile/perfmon.c | 2 | ||||
-rw-r--r-- | xen/arch/x86/oprofile/backtrace.c | 120 | ||||
-rw-r--r-- | xen/common/xenoprof.c | 6 | ||||
-rw-r--r-- | xen/include/public/xenoprof.h | 2 | ||||
-rw-r--r-- | xen/include/xen/xenoprof.h | 4 |
5 files changed, 83 insertions, 51 deletions
diff --git a/xen/arch/ia64/xen/oprofile/perfmon.c b/xen/arch/ia64/xen/oprofile/perfmon.c index 26fb693aeb..ada2b2c488 100644 --- a/xen/arch/ia64/xen/oprofile/perfmon.c +++ b/xen/arch/ia64/xen/oprofile/perfmon.c @@ -38,8 +38,6 @@ #include <asm/vmx.h> /* for vmx_user_mode() */ // XXX move them to an appropriate header file -extern void xenoprof_log_event(struct vcpu *vcpu, struct pt_regs * regs, - unsigned long eip, int mode, int event); extern int is_active(struct domain *d); static int allow_virq; diff --git a/xen/arch/x86/oprofile/backtrace.c b/xen/arch/x86/oprofile/backtrace.c index ad0b6eb0aa..6df0f181ef 100644 --- a/xen/arch/x86/oprofile/backtrace.c +++ b/xen/arch/x86/oprofile/backtrace.c @@ -16,48 +16,82 @@ #include<asm/guest_access.h> struct frame_head { - struct frame_head * ebp; - unsigned long ret; + struct frame_head * ebp; + unsigned long ret; } __attribute__((packed)); +#ifdef CONFIG_X86_64 +struct frame_head_32bit { + uint32_t ebp; + unsigned long ret; +} __attribute__((packed)); +#endif + static struct frame_head * dump_hypervisor_backtrace(struct domain *d, struct vcpu *vcpu, struct frame_head * head, int mode) { - if (!xenoprof_add_trace(d, vcpu, head->ret, mode)) - return 0; - - /* frame pointers should strictly progress back up the stack - * (towards higher addresses) */ - if (head >= head->ebp) - return NULL; + if (!xenoprof_add_trace(d, vcpu, head->ret, mode)) + return 0; + + /* frame pointers should strictly progress back up the stack + * (towards higher addresses) */ + if (head >= head->ebp) + return NULL; + + return head->ebp; +} - return head->ebp; +#ifdef CONFIG_X86_64 +static inline int is_32bit_vcpu(struct vcpu *vcpu) +{ + if (is_hvm_vcpu(vcpu)) + return !hvm_long_mode_enabled(vcpu); + else + return is_pv_32bit_vcpu(vcpu); } +#endif static struct frame_head * dump_guest_backtrace(struct domain *d, struct vcpu *vcpu, struct frame_head * head, int mode) { - struct frame_head bufhead[2]; - XEN_GUEST_HANDLE(char) guest_head = guest_handle_from_ptr(head, char); - - /* Also check accessibility of one struct frame_head beyond */ - if (!guest_handle_okay(guest_head, sizeof(bufhead))) - return 0; - if (__copy_from_guest_offset((char *)bufhead, guest_head, 0, - sizeof(bufhead))) - return 0; - - if (!xenoprof_add_trace(d, vcpu, bufhead[0].ret, mode)) - return 0; + struct frame_head bufhead[2]; + XEN_GUEST_HANDLE(char) guest_head = guest_handle_from_ptr(head, char); - /* frame pointers should strictly progress back up the stack - * (towards higher addresses) */ - if (head >= bufhead[0].ebp) - return NULL; - - return bufhead[0].ebp; +#ifdef CONFIG_X86_64 + if ( is_32bit_vcpu(vcpu) ) + { + struct frame_head_32bit bufhead32[2]; + /* Also check accessibility of one struct frame_head beyond */ + if (!guest_handle_okay(guest_head, sizeof(bufhead32))) + return 0; + if (__copy_from_guest_offset((char *)bufhead32, guest_head, 0, + sizeof(bufhead32))) + return 0; + bufhead[0].ebp=(struct frame_head *)(unsigned long)bufhead32[0].ebp; + bufhead[0].ret=bufhead32[0].ret; + } + else +#endif + { + /* Also check accessibility of one struct frame_head beyond */ + if (!guest_handle_okay(guest_head, sizeof(bufhead))) + return 0; + if (__copy_from_guest_offset((char *)bufhead, guest_head, 0, + sizeof(bufhead))) + return 0; + } + + if (!xenoprof_add_trace(d, vcpu, bufhead[0].ret, mode)) + return 0; + + /* frame pointers should strictly progress back up the stack + * (towards higher addresses) */ + if (head >= bufhead[0].ebp) + return NULL; + + return bufhead[0].ebp; } /* @@ -94,22 +128,22 @@ dump_guest_backtrace(struct domain *d, struct vcpu *vcpu, static int valid_hypervisor_stack(struct frame_head * head, struct cpu_user_regs * regs) { - unsigned long headaddr = (unsigned long)head; + unsigned long headaddr = (unsigned long)head; #ifdef CONFIG_X86_64 - unsigned long stack = (unsigned long)regs->rsp; + unsigned long stack = (unsigned long)regs->rsp; #else - unsigned long stack = (unsigned long)regs; + unsigned long stack = (unsigned long)regs; #endif - unsigned long stack_base = (stack & ~(STACK_SIZE - 1)) + STACK_SIZE; + unsigned long stack_base = (stack & ~(STACK_SIZE - 1)) + STACK_SIZE; - return headaddr > stack && headaddr < stack_base; + return headaddr > stack && headaddr < stack_base; } #else /* without fp, it's just junk */ static int valid_hypervisor_stack(struct frame_head * head, struct cpu_user_regs * regs) { - return 0; + return 0; } #endif @@ -117,16 +151,16 @@ void xenoprof_backtrace(struct domain *d, struct vcpu *vcpu, struct cpu_user_regs * const regs, unsigned long depth, int mode) { - struct frame_head *head; + struct frame_head *head; - head = (struct frame_head *)regs->ebp; + head = (struct frame_head *)regs->ebp; - if (mode > 1) { - while (depth-- && valid_hypervisor_stack(head, regs)) - head = dump_hypervisor_backtrace(d, vcpu, head, mode); - return; - } + if (mode > 1) { + while (depth-- && valid_hypervisor_stack(head, regs)) + head = dump_hypervisor_backtrace(d, vcpu, head, mode); + return; + } - while (depth-- && head) - head = dump_guest_backtrace(d, vcpu, head, mode); + while (depth-- && head) + head = dump_guest_backtrace(d, vcpu, head, mode); } diff --git a/xen/common/xenoprof.c b/xen/common/xenoprof.c index 74d988a305..70ae18b7bf 100644 --- a/xen/common/xenoprof.c +++ b/xen/common/xenoprof.c @@ -479,7 +479,7 @@ static int xenoprof_buf_space(struct domain *d, xenoprof_buf_t * buf, int size) /* Check for space and add a sample. Return 1 if successful, 0 otherwise. */ static int xenoprof_add_sample(struct domain *d, xenoprof_buf_t *buf, - unsigned long eip, int mode, int event) + uint64_t eip, int mode, int event) { int head, tail, size; @@ -516,7 +516,7 @@ static int xenoprof_add_sample(struct domain *d, xenoprof_buf_t *buf, } int xenoprof_add_trace(struct domain *d, struct vcpu *vcpu, - unsigned long eip, int mode) + uint64_t eip, int mode) { xenoprof_buf_t *buf = d->xenoprof->vcpu[vcpu->vcpu_id].buffer; @@ -531,7 +531,7 @@ int xenoprof_add_trace(struct domain *d, struct vcpu *vcpu, } void xenoprof_log_event(struct vcpu *vcpu, - struct cpu_user_regs * regs, unsigned long eip, + struct cpu_user_regs * regs, uint64_t eip, int mode, int event) { struct domain *d = vcpu->domain; diff --git a/xen/include/public/xenoprof.h b/xen/include/public/xenoprof.h index 346d6c514c..a0c6987c77 100644 --- a/xen/include/public/xenoprof.h +++ b/xen/include/public/xenoprof.h @@ -68,7 +68,7 @@ struct event_log { }; /* PC value that indicates a special code */ -#define XENOPROF_ESCAPE_CODE ~0UL +#define XENOPROF_ESCAPE_CODE (~0ULL) /* Transient events for the xenoprof->oprofile cpu buf */ #define XENOPROF_TRACE_BEGIN 1 diff --git a/xen/include/xen/xenoprof.h b/xen/include/xen/xenoprof.h index 5b38e614da..0aa7f0d5d2 100644 --- a/xen/include/xen/xenoprof.h +++ b/xen/include/xen/xenoprof.h @@ -69,7 +69,7 @@ int is_passive(struct domain *d); void free_xenoprof_pages(struct domain *d); int xenoprof_add_trace(struct domain *d, struct vcpu *v, - unsigned long eip, int mode); + uint64_t eip, int mode); #define PMU_OWNER_NONE 0 #define PMU_OWNER_XENOPROF 1 @@ -78,7 +78,7 @@ int acquire_pmu_ownship(int pmu_ownership); void release_pmu_ownship(int pmu_ownership); void xenoprof_log_event(struct vcpu *vcpu, - struct cpu_user_regs * regs, unsigned long eip, + struct cpu_user_regs * regs, uint64_t eip, int mode, int event); #endif /* __XEN__XENOPROF_H__ */ |