aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorge Dunlap <george.dunlap@eu.citrix.com>2012-03-07 10:58:25 +0000
committerGeorge Dunlap <george.dunlap@eu.citrix.com>2012-03-07 10:58:25 +0000
commit11d7e56fff6dd5305d71216a684d74f20d77cc1a (patch)
tree05df8dea07590d256f644d330a06df524d275baa
parent19de40af1abe3606632ed115af9d82b326fe97bb (diff)
downloadxen-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.c2
-rw-r--r--xen/arch/x86/oprofile/backtrace.c120
-rw-r--r--xen/common/xenoprof.c6
-rw-r--r--xen/include/public/xenoprof.h2
-rw-r--r--xen/include/xen/xenoprof.h4
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__ */