aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2007-12-14 10:34:22 +0000
committerKeir Fraser <keir.fraser@citrix.com>2007-12-14 10:34:22 +0000
commite20250f070772b6cdfa8309e9acad14ef0dfc10c (patch)
tree289909a86b4ddcea0ceced2be28f8ca767f4e456
parent80197aaf427fe32302e8cbfc84a1aeeedfdc80df (diff)
downloadxen-e20250f070772b6cdfa8309e9acad14ef0dfc10c.tar.gz
xen-e20250f070772b6cdfa8309e9acad14ef0dfc10c.tar.bz2
xen-e20250f070772b6cdfa8309e9acad14ef0dfc10c.zip
xenoprof: Fix more than one events can't be sampled concurrently for Intel CPU with family equal to 6
The original code only sets EN bit of IA32_PERFEVTSEL0 when profiling is started. Signed-off-by: Xiaowei Yang <xiaowei.yang@intel.com>
-rw-r--r--xen/arch/x86/oprofile/op_model_ppro.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/xen/arch/x86/oprofile/op_model_ppro.c b/xen/arch/x86/oprofile/op_model_ppro.c
index 6c4344ee21..53ff2182c2 100644
--- a/xen/arch/x86/oprofile/op_model_ppro.c
+++ b/xen/arch/x86/oprofile/op_model_ppro.c
@@ -104,6 +104,8 @@ static int ppro_check_ctrs(unsigned int const cpu,
int mode = xenoprofile_get_mode(current, regs);
for (i = 0 ; i < NUM_COUNTERS; ++i) {
+ if (!reset_value[i])
+ continue;
CTR_READ(low, high, msrs, i);
if (CTR_OVERFLOWED(low)) {
xenoprof_log_event(current, regs, eip, mode, i);
@@ -123,18 +125,30 @@ static int ppro_check_ctrs(unsigned int const cpu,
static void ppro_start(struct op_msrs const * const msrs)
{
unsigned int low,high;
- CTRL_READ(low, high, msrs, 0);
- CTRL_SET_ACTIVE(low);
- CTRL_WRITE(low, high, msrs, 0);
+ int i;
+
+ for (i = 0; i < NUM_COUNTERS; ++i) {
+ if (reset_value[i]) {
+ CTRL_READ(low, high, msrs, i);
+ CTRL_SET_ACTIVE(low);
+ CTRL_WRITE(low, high, msrs, i);
+ }
+ }
}
static void ppro_stop(struct op_msrs const * const msrs)
{
unsigned int low,high;
- CTRL_READ(low, high, msrs, 0);
- CTRL_SET_INACTIVE(low);
- CTRL_WRITE(low, high, msrs, 0);
+ int i;
+
+ for (i = 0; i < NUM_COUNTERS; ++i) {
+ if (!reset_value[i])
+ continue;
+ CTRL_READ(low, high, msrs, i);
+ CTRL_SET_INACTIVE(low);
+ CTRL_WRITE(low, high, msrs, i);
+ }
}