diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2007-12-14 10:34:22 +0000 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2007-12-14 10:34:22 +0000 |
commit | e20250f070772b6cdfa8309e9acad14ef0dfc10c (patch) | |
tree | 289909a86b4ddcea0ceced2be28f8ca767f4e456 | |
parent | 80197aaf427fe32302e8cbfc84a1aeeedfdc80df (diff) | |
download | xen-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.c | 26 |
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); + } } |