diff options
-rw-r--r-- | arch/x86/oprofile/op_model_amd.c | 16 | ||||
-rw-r--r-- | arch/x86/oprofile/op_model_p4.c | 6 | ||||
-rw-r--r-- | arch/x86/oprofile/op_model_ppro.c | 10 |
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 | |||
34 | static unsigned long reset_value[NUM_COUNTERS]; | 33 | static 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) { } | |||
241 | static int op_amd_check_ctrs(struct pt_regs * const regs, | 240 | static 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 | |||
35 | static unsigned int num_counters = NUM_COUNTERS_NON_HT; | 37 | static unsigned int num_counters = NUM_COUNTERS_NON_HT; |
36 | static unsigned int num_controls = NUM_CONTROLS_NON_HT; | 38 | static 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 @@ | |||
26 | static int num_counters = 2; | 26 | static int num_counters = 2; |
27 | static int counter_width = 32; | 27 | static 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 | ||
33 | static u64 *reset_value; | 31 | static 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 |