aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/oprofile/op_model_amd.c16
-rw-r--r--arch/x86/oprofile/op_model_p4.c6
-rw-r--r--arch/x86/oprofile/op_model_ppro.c10
3 files changed, 15 insertions, 17 deletions
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c
index 2406ab863605..b5d678fbf038 100644
--- a/arch/x86/oprofile/op_model_amd.c
+++ b/arch/x86/oprofile/op_model_amd.c
@@ -26,11 +26,10 @@
26#define NUM_COUNTERS 4 26#define NUM_COUNTERS 4
27#define NUM_CONTROLS 4 27#define NUM_CONTROLS 4
28#define OP_EVENT_MASK 0x0FFF 28#define OP_EVENT_MASK 0x0FFF
29#define OP_CTR_OVERFLOW (1ULL<<31)
29 30
30#define MSR_AMD_EVENTSEL_RESERVED ((0xFFFFFCF0ULL<<32)|(1ULL<<21)) 31#define MSR_AMD_EVENTSEL_RESERVED ((0xFFFFFCF0ULL<<32)|(1ULL<<21))
31 32
32#define CTR_OVERFLOWED(n) (!((n) & (1U<<31)))
33
34static unsigned long reset_value[NUM_COUNTERS]; 33static unsigned long reset_value[NUM_COUNTERS];
35 34
36#ifdef CONFIG_OPROFILE_IBS 35#ifdef CONFIG_OPROFILE_IBS
@@ -241,17 +240,18 @@ static inline void op_amd_stop_ibs(void) { }
241static int op_amd_check_ctrs(struct pt_regs * const regs, 240static int op_amd_check_ctrs(struct pt_regs * const regs,
242 struct op_msrs const * const msrs) 241 struct op_msrs const * const msrs)
243{ 242{
244 unsigned int low, high; 243 u64 val;
245 int i; 244 int i;
246 245
247 for (i = 0 ; i < NUM_COUNTERS; ++i) { 246 for (i = 0 ; i < NUM_COUNTERS; ++i) {
248 if (!reset_value[i]) 247 if (!reset_value[i])
249 continue; 248 continue;
250 rdmsr(msrs->counters[i].addr, low, high); 249 rdmsrl(msrs->counters[i].addr, val);
251 if (CTR_OVERFLOWED(low)) { 250 /* bit is clear if overflowed: */
252 oprofile_add_sample(regs, i); 251 if (val & OP_CTR_OVERFLOW)
253 wrmsr(msrs->counters[i].addr, -(unsigned int)reset_value[i], -1); 252 continue;
254 } 253 oprofile_add_sample(regs, i);
254 wrmsr(msrs->counters[i].addr, -(unsigned int)reset_value[i], -1);
255 } 255 }
256 256
257 op_amd_handle_ibs(regs, msrs); 257 op_amd_handle_ibs(regs, msrs);
diff --git a/arch/x86/oprofile/op_model_p4.c b/arch/x86/oprofile/op_model_p4.c
index 05ba0287b1f7..ac4ca28b9ed5 100644
--- a/arch/x86/oprofile/op_model_p4.c
+++ b/arch/x86/oprofile/op_model_p4.c
@@ -32,6 +32,8 @@
32#define NUM_CCCRS_HT2 9 32#define NUM_CCCRS_HT2 9
33#define NUM_CONTROLS_HT2 (NUM_ESCRS_HT2 + NUM_CCCRS_HT2) 33#define NUM_CONTROLS_HT2 (NUM_ESCRS_HT2 + NUM_CCCRS_HT2)
34 34
35#define OP_CTR_OVERFLOW (1ULL<<31)
36
35static unsigned int num_counters = NUM_COUNTERS_NON_HT; 37static unsigned int num_counters = NUM_COUNTERS_NON_HT;
36static unsigned int num_controls = NUM_CONTROLS_NON_HT; 38static unsigned int num_controls = NUM_CONTROLS_NON_HT;
37 39
@@ -362,8 +364,6 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
362#define CCCR_OVF_P(cccr) ((cccr) & (1U<<31)) 364#define CCCR_OVF_P(cccr) ((cccr) & (1U<<31))
363#define CCCR_CLEAR_OVF(cccr) ((cccr) &= (~(1U<<31))) 365#define CCCR_CLEAR_OVF(cccr) ((cccr) &= (~(1U<<31)))
364 366
365#define CTR_OVERFLOW_P(ctr) (!((ctr) & 0x80000000))
366
367 367
368/* this assigns a "stagger" to the current CPU, which is used throughout 368/* this assigns a "stagger" to the current CPU, which is used throughout
369 the code in this module as an extra array offset, to select the "even" 369 the code in this module as an extra array offset, to select the "even"
@@ -622,7 +622,7 @@ static int p4_check_ctrs(struct pt_regs * const regs,
622 622
623 rdmsr(p4_counters[real].cccr_address, low, high); 623 rdmsr(p4_counters[real].cccr_address, low, high);
624 rdmsr(p4_counters[real].counter_address, ctr, high); 624 rdmsr(p4_counters[real].counter_address, ctr, high);
625 if (CCCR_OVF_P(low) || CTR_OVERFLOW_P(ctr)) { 625 if (CCCR_OVF_P(low) || !(ctr & OP_CTR_OVERFLOW)) {
626 oprofile_add_sample(regs, i); 626 oprofile_add_sample(regs, i);
627 wrmsr(p4_counters[real].counter_address, 627 wrmsr(p4_counters[real].counter_address,
628 -(u32)reset_value[i], -1); 628 -(u32)reset_value[i], -1);
diff --git a/arch/x86/oprofile/op_model_ppro.c b/arch/x86/oprofile/op_model_ppro.c
index 3092f998baf2..82db396dc3ef 100644
--- a/arch/x86/oprofile/op_model_ppro.c
+++ b/arch/x86/oprofile/op_model_ppro.c
@@ -26,8 +26,6 @@
26static int num_counters = 2; 26static int num_counters = 2;
27static int counter_width = 32; 27static int counter_width = 32;
28 28
29#define CTR_OVERFLOWED(n) (!((n) & (1ULL<<(counter_width-1))))
30
31#define MSR_PPRO_EVENTSEL_RESERVED ((0xFFFFFFFFULL<<32)|(1ULL<<21)) 29#define MSR_PPRO_EVENTSEL_RESERVED ((0xFFFFFFFFULL<<32)|(1ULL<<21))
32 30
33static u64 *reset_value; 31static u64 *reset_value;
@@ -124,10 +122,10 @@ static int ppro_check_ctrs(struct pt_regs * const regs,
124 if (!reset_value[i]) 122 if (!reset_value[i])
125 continue; 123 continue;
126 rdmsrl(msrs->counters[i].addr, val); 124 rdmsrl(msrs->counters[i].addr, val);
127 if (CTR_OVERFLOWED(val)) { 125 if (val & (1ULL << (counter_width - 1)))
128 oprofile_add_sample(regs, i); 126 continue;
129 wrmsrl(msrs->counters[i].addr, -reset_value[i]); 127 oprofile_add_sample(regs, i);
130 } 128 wrmsrl(msrs->counters[i].addr, -reset_value[i]);
131 } 129 }
132 130
133 /* Only P6 based Pentium M need to re-unmask the apic vector but it 131 /* Only P6 based Pentium M need to re-unmask the apic vector but it