diff options
author | Alex Williamson <alex.williamson@hp.com> | 2007-12-17 09:38:54 -0700 |
---|---|---|
committer | Alex Williamson <alex.williamson@hp.com> | 2007-12-17 09:38:54 -0700 |
commit | 4662025edbd18b601974627996e5ece0c71fd28f (patch) | |
tree | 9011e9a1279a123252fa8570630ac15ae187ab3a | |
parent | 0a021885d09ff6a022f77dc2116eea1cc6e02474 (diff) | |
download | xen-4662025edbd18b601974627996e5ece0c71fd28f.tar.gz xen-4662025edbd18b601974627996e5ece0c71fd28f.tar.bz2 xen-4662025edbd18b601974627996e5ece0c71fd28f.zip |
[IA64] xenoprof: fix xenoprof_handler()
- Use profile_pc() to get instruction pointer.
- Make xenoprof_handler() VTi domain aware
- Pass current to xenoprofile_get_mode() instead of task=NULL.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
-rw-r--r-- | xen/arch/ia64/xen/oprofile/perfmon.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/xen/arch/ia64/xen/oprofile/perfmon.c b/xen/arch/ia64/xen/oprofile/perfmon.c index f9298e056f..26fb693aeb 100644 --- a/xen/arch/ia64/xen/oprofile/perfmon.c +++ b/xen/arch/ia64/xen/oprofile/perfmon.c @@ -35,6 +35,7 @@ #include <xen/xenoprof.h> #include <asm/perfmon.h> #include <asm/ptrace.h> +#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, @@ -45,24 +46,37 @@ static int allow_virq; static int allow_ints; static int +xenoprof_is_xen_mode(struct vcpu *v, struct pt_regs *regs) +{ + if (VMX_DOMAIN(v)) + return !vmx_user_mode(regs); + return ring_0(regs); +} + +static int xenoprof_handler(struct task_struct *task, void *buf, pfm_ovfl_arg_t *arg, struct pt_regs *regs, unsigned long stamp) { - unsigned long ip = regs->cr_iip; + unsigned long ip = profile_pc(regs); int event = arg->pmd_eventid; - + struct vcpu *v = current; + int mode = xenoprofile_get_mode(v, regs); + + // see pfm_do_interrupt_handler() in xen/arch/ia64/linux-xen/perfmon.c. + // It always passes task as NULL. This is work around + BUG_ON(task != NULL); + arg->ovfl_ctrl.bits.reset_ovfl_pmds = 1; if (!allow_virq || !allow_ints) return 0; // Note that log event actually expect cpu_user_regs, cast back // appropriately when doing the backtrace implementation in ia64 - xenoprof_log_event(current, regs, ip, xenoprofile_get_mode(task, regs), - event); - + xenoprof_log_event(v, regs, ip, mode, event); // send VIRQ_XENOPROF - if (is_active(current->domain) && !ring_0(regs)) - send_guest_vcpu_virq(current, VIRQ_XENOPROF); + if (is_active(v->domain) && !xenoprof_is_xen_mode(v, regs) && + !is_idle_vcpu(v)) + send_guest_vcpu_virq(v, VIRQ_XENOPROF); return 0; } |