ia64/xen-unstable

changeset 16629:9a545d45b192

[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>
author Alex Williamson <alex.williamson@hp.com>
date Mon Dec 17 09:38:54 2007 -0700 (2007-12-17)
parents e88253dfefdc
children 57eec263d48b
files xen/arch/ia64/xen/oprofile/perfmon.c
line diff
     1.1 --- a/xen/arch/ia64/xen/oprofile/perfmon.c	Mon Dec 17 09:36:46 2007 -0700
     1.2 +++ b/xen/arch/ia64/xen/oprofile/perfmon.c	Mon Dec 17 09:38:54 2007 -0700
     1.3 @@ -35,6 +35,7 @@
     1.4  #include <xen/xenoprof.h>
     1.5  #include <asm/perfmon.h>
     1.6  #include <asm/ptrace.h>
     1.7 +#include <asm/vmx.h>    /* for vmx_user_mode() */
     1.8  
     1.9  // XXX move them to an appropriate header file
    1.10  extern void xenoprof_log_event(struct vcpu *vcpu, struct pt_regs * regs,
    1.11 @@ -45,24 +46,37 @@ static int allow_virq;
    1.12  static int allow_ints;
    1.13  
    1.14  static int
    1.15 +xenoprof_is_xen_mode(struct vcpu *v, struct pt_regs *regs)
    1.16 +{
    1.17 +    if (VMX_DOMAIN(v))
    1.18 +        return !vmx_user_mode(regs);
    1.19 +    return ring_0(regs);
    1.20 +}
    1.21 +
    1.22 +static int
    1.23  xenoprof_handler(struct task_struct *task, void *buf, pfm_ovfl_arg_t *arg,
    1.24                   struct pt_regs *regs, unsigned long stamp)
    1.25  {
    1.26 -    unsigned long ip = regs->cr_iip;
    1.27 +    unsigned long ip = profile_pc(regs);
    1.28      int event = arg->pmd_eventid;
    1.29 - 
    1.30 +    struct vcpu *v = current;
    1.31 +    int mode = xenoprofile_get_mode(v, regs);
    1.32 +
    1.33 +    // see pfm_do_interrupt_handler() in xen/arch/ia64/linux-xen/perfmon.c.
    1.34 +    // It always passes task as NULL. This is work around
    1.35 +    BUG_ON(task != NULL);
    1.36 +
    1.37      arg->ovfl_ctrl.bits.reset_ovfl_pmds = 1;
    1.38      if (!allow_virq || !allow_ints)
    1.39          return 0;
    1.40  
    1.41      // Note that log event actually expect cpu_user_regs, cast back 
    1.42      // appropriately when doing the backtrace implementation in ia64
    1.43 -    xenoprof_log_event(current, regs, ip, xenoprofile_get_mode(task, regs), 
    1.44 -					   event);
    1.45 -    
    1.46 +    xenoprof_log_event(v, regs, ip, mode, event);
    1.47      // send VIRQ_XENOPROF
    1.48 -    if (is_active(current->domain) && !ring_0(regs))
    1.49 -        send_guest_vcpu_virq(current, VIRQ_XENOPROF);
    1.50 +    if (is_active(v->domain) && !xenoprof_is_xen_mode(v, regs) &&
    1.51 +        !is_idle_vcpu(v))
    1.52 +        send_guest_vcpu_virq(v, VIRQ_XENOPROF);
    1.53  
    1.54      return 0;
    1.55  }