aboutsummaryrefslogtreecommitdiffstats
path: root/xen/common/xenoprof.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-01-30 09:59:27 +0000
committerKeir Fraser <keir.fraser@citrix.com>2008-01-30 09:59:27 +0000
commit03406ca94c130f948a7b8e36cfa4172600054f49 (patch)
treed99cb72e990a18538995449a3985a6864f8509b1 /xen/common/xenoprof.c
parenta1d430b3091bdd486816b907f2bc27b284347f34 (diff)
downloadxen-03406ca94c130f948a7b8e36cfa4172600054f49.tar.gz
xen-03406ca94c130f948a7b8e36cfa4172600054f49.tar.bz2
xen-03406ca94c130f948a7b8e36cfa4172600054f49.zip
vmx: Enable Core 2 Duo Performance Counters in HVM guest
Signed-off-by: Haitao Shan <haitao.shan@intel.com>
Diffstat (limited to 'xen/common/xenoprof.c')
-rw-r--r--xen/common/xenoprof.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/xen/common/xenoprof.c b/xen/common/xenoprof.c
index 741c9f04d3..f41ebb9069 100644
--- a/xen/common/xenoprof.c
+++ b/xen/common/xenoprof.c
@@ -23,6 +23,10 @@
/* Lock protecting the following global state */
static DEFINE_SPINLOCK(xenoprof_lock);
+static DEFINE_SPINLOCK(pmu_owner_lock);
+int pmu_owner = 0;
+int pmu_hvm_refcount = 0;
+
static struct domain *active_domains[MAX_OPROF_DOMAINS];
static int active_ready[MAX_OPROF_DOMAINS];
static unsigned int adomains;
@@ -44,6 +48,37 @@ static u64 passive_samples;
static u64 idle_samples;
static u64 others_samples;
+int acquire_pmu_ownership(int pmu_ownship)
+{
+ spin_lock(&pmu_owner_lock);
+ if ( pmu_owner == PMU_OWNER_NONE )
+ {
+ pmu_owner = pmu_ownship;
+ goto out;
+ }
+
+ if ( pmu_owner == pmu_ownship )
+ goto out;
+
+ spin_unlock(&pmu_owner_lock);
+ return 0;
+ out:
+ if ( pmu_owner == PMU_OWNER_HVM )
+ pmu_hvm_refcount++;
+ spin_unlock(&pmu_owner_lock);
+ return 1;
+}
+
+void release_pmu_ownship(int pmu_ownship)
+{
+ spin_lock(&pmu_owner_lock);
+ if ( pmu_ownship == PMU_OWNER_HVM )
+ pmu_hvm_refcount--;
+ if ( !pmu_hvm_refcount )
+ pmu_owner = PMU_OWNER_NONE;
+ spin_unlock(&pmu_owner_lock);
+}
+
int is_active(struct domain *d)
{
struct xenoprof *x = d->xenoprof;
@@ -649,6 +684,11 @@ int do_xenoprof_op(int op, XEN_GUEST_HANDLE(void) arg)
break;
case XENOPROF_get_buffer:
+ if ( !acquire_pmu_ownership(PMU_OWNER_XENOPROF) )
+ {
+ ret = -EBUSY;
+ break;
+ }
ret = xenoprof_op_get_buffer(arg);
break;
@@ -786,6 +826,7 @@ int do_xenoprof_op(int op, XEN_GUEST_HANDLE(void) arg)
break;
x = current->domain->xenoprof;
unshare_xenoprof_page_with_guest(x);
+ release_pmu_ownship(PMU_OWNER_XENOPROF);
break;
}