ia64/xen-unstable

changeset 11833:6ed4368b4a9e 3.0.3-branched

[XENOPROF] Add a lock around the xenoprof hypercall. It mutates global state.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
author kfraser@localhost.localdomain
date Sun Oct 15 09:53:20 2006 +0100 (2006-10-15)
parents d30ed0e261ae
children 3cc0b589c235
files xen/arch/x86/oprofile/xenoprof.c
line diff
     1.1 --- a/xen/arch/x86/oprofile/xenoprof.c	Sun Oct 15 09:52:33 2006 +0100
     1.2 +++ b/xen/arch/x86/oprofile/xenoprof.c	Sun Oct 15 09:53:20 2006 +0100
     1.3 @@ -13,6 +13,9 @@
     1.4  /* Limit amount of pages used for shared buffer (per domain) */
     1.5  #define MAX_OPROF_SHARED_PAGES 32
     1.6  
     1.7 +/* Lock protecting the following global state */
     1.8 +static spinlock_t xenoprof_lock = SPIN_LOCK_UNLOCKED;
     1.9 +
    1.10  struct domain *active_domains[MAX_OPROF_DOMAINS];
    1.11  int active_ready[MAX_OPROF_DOMAINS];
    1.12  unsigned int adomains;
    1.13 @@ -514,6 +517,8 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
    1.14          return -EPERM;
    1.15      }
    1.16  
    1.17 +    spin_lock(&xenoprof_lock);
    1.18 +    
    1.19      switch ( op )
    1.20      {
    1.21      case XENOPROF_init:
    1.22 @@ -539,23 +544,31 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
    1.23      case XENOPROF_set_active:
    1.24      {
    1.25          domid_t domid;
    1.26 -        if ( xenoprof_state != XENOPROF_IDLE )
    1.27 -            return -EPERM;
    1.28 -        if ( copy_from_guest(&domid, arg, 1) )
    1.29 -            return -EFAULT;
    1.30 +        if ( xenoprof_state != XENOPROF_IDLE ) {
    1.31 +            ret = -EPERM;
    1.32 +            break;
    1.33 +        }
    1.34 +        if ( copy_from_guest(&domid, arg, 1) ) {
    1.35 +            ret = -EFAULT;
    1.36 +            break;
    1.37 +        }
    1.38          ret = add_active_list(domid);
    1.39          break;
    1.40      }
    1.41      case XENOPROF_set_passive:
    1.42      {
    1.43 -        if ( xenoprof_state != XENOPROF_IDLE )
    1.44 -            return -EPERM;
    1.45 +        if ( xenoprof_state != XENOPROF_IDLE ) {
    1.46 +            ret = -EPERM;
    1.47 +            break;
    1.48 +        }
    1.49          ret = add_passive_list(arg);
    1.50          break;
    1.51      }
    1.52      case XENOPROF_reserve_counters:
    1.53 -        if ( xenoprof_state != XENOPROF_IDLE )
    1.54 -            return -EPERM;
    1.55 +        if ( xenoprof_state != XENOPROF_IDLE ) {
    1.56 +            ret = -EPERM;
    1.57 +            break;
    1.58 +        }
    1.59          ret = nmi_reserve_counters();
    1.60          if ( !ret )
    1.61              xenoprof_state = XENOPROF_COUNTERS_RESERVED;
    1.62 @@ -564,16 +577,20 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
    1.63      case XENOPROF_counter:
    1.64      {
    1.65          struct xenoprof_counter counter;
    1.66 -        if ( xenoprof_state != XENOPROF_COUNTERS_RESERVED )
    1.67 -            return -EPERM;
    1.68 -        if ( adomains == 0 )
    1.69 -            return -EPERM;
    1.70 +        if ( xenoprof_state != XENOPROF_COUNTERS_RESERVED || adomains == 0) {
    1.71 +            ret = -EPERM;
    1.72 +            break;
    1.73 +        }
    1.74  
    1.75 -        if ( copy_from_guest(&counter, arg, 1) )
    1.76 -            return -EFAULT;
    1.77 +        if ( copy_from_guest(&counter, arg, 1) ) {
    1.78 +            ret = -EFAULT;
    1.79 +            break;
    1.80 +        }
    1.81  
    1.82 -        if ( counter.ind > OP_MAX_COUNTER )
    1.83 -            return -E2BIG;
    1.84 +        if ( counter.ind > OP_MAX_COUNTER ) {
    1.85 +            ret = -E2BIG;
    1.86 +            break;
    1.87 +        }
    1.88  
    1.89          counter_config[counter.ind].count     = (unsigned long) counter.count;
    1.90          counter_config[counter.ind].enabled   = (unsigned long) counter.enabled;
    1.91 @@ -587,8 +604,10 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
    1.92      }
    1.93  
    1.94      case XENOPROF_setup_events:
    1.95 -        if ( xenoprof_state != XENOPROF_COUNTERS_RESERVED )
    1.96 -            return -EPERM;
    1.97 +        if ( xenoprof_state != XENOPROF_COUNTERS_RESERVED ) {
    1.98 +            ret = -EPERM;
    1.99 +            break;
   1.100 +        }
   1.101          ret = nmi_setup_events();
   1.102          if ( !ret )
   1.103              xenoprof_state = XENOPROF_READY;
   1.104 @@ -621,16 +640,20 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
   1.105          break;
   1.106  
   1.107      case XENOPROF_stop:
   1.108 -        if ( xenoprof_state != XENOPROF_PROFILING )
   1.109 -            return -EPERM;
   1.110 +        if ( xenoprof_state != XENOPROF_PROFILING ) {
   1.111 +            ret = -EPERM;
   1.112 +            break;
   1.113 +        }
   1.114          nmi_stop();
   1.115          xenoprof_state = XENOPROF_READY;
   1.116          break;
   1.117  
   1.118      case XENOPROF_disable_virq:
   1.119          if ( (xenoprof_state == XENOPROF_PROFILING) && 
   1.120 -             (is_active(current->domain)) )
   1.121 -            return -EPERM;
   1.122 +             (is_active(current->domain)) ) {
   1.123 +            ret = -EPERM;
   1.124 +            break;
   1.125 +        }
   1.126          ret = reset_active(current->domain);
   1.127          break;
   1.128  
   1.129 @@ -662,6 +685,8 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
   1.130          ret = -EINVAL;
   1.131      }
   1.132  
   1.133 +    spin_unlock(&xenoprof_lock);
   1.134 +
   1.135      if ( ret < 0 )
   1.136          printk("xenoprof: operation %d failed for dom %d (status : %d)\n",
   1.137                 op, current->domain->domain_id, ret);