[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [XENOPROF] Add a lock around the xenoprof hypercall. It mutates global state.
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Node ID 6ed4368b4a9e1924c983774c4b1a2b6baf8e98a6 # Parent d30ed0e261aec5ab7ce1904ae1007f3af4898b92 [XENOPROF] Add a lock around the xenoprof hypercall. It mutates global state. Signed-off-by: Markus Armbruster <armbru@xxxxxxxxxx> --- xen/arch/x86/oprofile/xenoprof.c | 73 ++++++++++++++++++++++++++------------- 1 files changed, 49 insertions(+), 24 deletions(-) diff -r d30ed0e261ae -r 6ed4368b4a9e xen/arch/x86/oprofile/xenoprof.c --- a/xen/arch/x86/oprofile/xenoprof.c Sun Oct 15 09:52:33 2006 +0100 +++ b/xen/arch/x86/oprofile/xenoprof.c Sun Oct 15 09:53:20 2006 +0100 @@ -12,6 +12,9 @@ /* Limit amount of pages used for shared buffer (per domain) */ #define MAX_OPROF_SHARED_PAGES 32 + +/* Lock protecting the following global state */ +static spinlock_t xenoprof_lock = SPIN_LOCK_UNLOCKED; struct domain *active_domains[MAX_OPROF_DOMAINS]; int active_ready[MAX_OPROF_DOMAINS]; @@ -514,6 +517,8 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN return -EPERM; } + spin_lock(&xenoprof_lock); + switch ( op ) { case XENOPROF_init: @@ -539,23 +544,31 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN case XENOPROF_set_active: { domid_t domid; - if ( xenoprof_state != XENOPROF_IDLE ) - return -EPERM; - if ( copy_from_guest(&domid, arg, 1) ) - return -EFAULT; + if ( xenoprof_state != XENOPROF_IDLE ) { + ret = -EPERM; + break; + } + if ( copy_from_guest(&domid, arg, 1) ) { + ret = -EFAULT; + break; + } ret = add_active_list(domid); break; } case XENOPROF_set_passive: { - if ( xenoprof_state != XENOPROF_IDLE ) - return -EPERM; + if ( xenoprof_state != XENOPROF_IDLE ) { + ret = -EPERM; + break; + } ret = add_passive_list(arg); break; } case XENOPROF_reserve_counters: - if ( xenoprof_state != XENOPROF_IDLE ) - return -EPERM; + if ( xenoprof_state != XENOPROF_IDLE ) { + ret = -EPERM; + break; + } ret = nmi_reserve_counters(); if ( !ret ) xenoprof_state = XENOPROF_COUNTERS_RESERVED; @@ -564,16 +577,20 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN case XENOPROF_counter: { struct xenoprof_counter counter; - if ( xenoprof_state != XENOPROF_COUNTERS_RESERVED ) - return -EPERM; - if ( adomains == 0 ) - return -EPERM; - - if ( copy_from_guest(&counter, arg, 1) ) - return -EFAULT; - - if ( counter.ind > OP_MAX_COUNTER ) - return -E2BIG; + if ( xenoprof_state != XENOPROF_COUNTERS_RESERVED || adomains == 0) { + ret = -EPERM; + break; + } + + if ( copy_from_guest(&counter, arg, 1) ) { + ret = -EFAULT; + break; + } + + if ( counter.ind > OP_MAX_COUNTER ) { + ret = -E2BIG; + break; + } counter_config[counter.ind].count = (unsigned long) counter.count; counter_config[counter.ind].enabled = (unsigned long) counter.enabled; @@ -587,8 +604,10 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN } case XENOPROF_setup_events: - if ( xenoprof_state != XENOPROF_COUNTERS_RESERVED ) - return -EPERM; + if ( xenoprof_state != XENOPROF_COUNTERS_RESERVED ) { + ret = -EPERM; + break; + } ret = nmi_setup_events(); if ( !ret ) xenoprof_state = XENOPROF_READY; @@ -621,16 +640,20 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN break; case XENOPROF_stop: - if ( xenoprof_state != XENOPROF_PROFILING ) - return -EPERM; + if ( xenoprof_state != XENOPROF_PROFILING ) { + ret = -EPERM; + break; + } nmi_stop(); xenoprof_state = XENOPROF_READY; break; case XENOPROF_disable_virq: if ( (xenoprof_state == XENOPROF_PROFILING) && - (is_active(current->domain)) ) - return -EPERM; + (is_active(current->domain)) ) { + ret = -EPERM; + break; + } ret = reset_active(current->domain); break; @@ -662,6 +685,8 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN ret = -EINVAL; } + spin_unlock(&xenoprof_lock); + if ( ret < 0 ) printk("xenoprof: operation %d failed for dom %d (status : %d)\n", op, current->domain->domain_id, ret); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |