|
@@ -753,19 +753,21 @@ out:
|
|
|
|
|
|
static inline int p4_pmu_clear_cccr_ovf(struct hw_perf_event *hwc)
|
|
|
{
|
|
|
- int overflow = 0;
|
|
|
- u32 low, high;
|
|
|
+ u64 v;
|
|
|
|
|
|
- rdmsr(hwc->config_base + hwc->idx, low, high);
|
|
|
-
|
|
|
- /* we need to check high bit for unflagged overflows */
|
|
|
- if ((low & P4_CCCR_OVF) || !(high & (1 << 31))) {
|
|
|
- overflow = 1;
|
|
|
- (void)checking_wrmsrl(hwc->config_base + hwc->idx,
|
|
|
- ((u64)low) & ~P4_CCCR_OVF);
|
|
|
+ /* an official way for overflow indication */
|
|
|
+ rdmsrl(hwc->config_base + hwc->idx, v);
|
|
|
+ if (v & P4_CCCR_OVF) {
|
|
|
+ wrmsrl(hwc->config_base + hwc->idx, v & ~P4_CCCR_OVF);
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
- return overflow;
|
|
|
+ /* it might be unflagged overflow */
|
|
|
+ rdmsrl(hwc->event_base + hwc->idx, v);
|
|
|
+ if (!(v & ARCH_P4_CNTRVAL_MASK))
|
|
|
+ return 1;
|
|
|
+
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
static void p4_pmu_disable_pebs(void)
|
|
@@ -1152,9 +1154,9 @@ static __initconst const struct x86_pmu p4_pmu = {
|
|
|
*/
|
|
|
.num_counters = ARCH_P4_MAX_CCCR,
|
|
|
.apic = 1,
|
|
|
- .cntval_bits = 40,
|
|
|
- .cntval_mask = (1ULL << 40) - 1,
|
|
|
- .max_period = (1ULL << 39) - 1,
|
|
|
+ .cntval_bits = ARCH_P4_CNTRVAL_BITS,
|
|
|
+ .cntval_mask = ARCH_P4_CNTRVAL_MASK,
|
|
|
+ .max_period = (1ULL << (ARCH_P4_CNTRVAL_BITS - 1)) - 1,
|
|
|
.hw_config = p4_hw_config,
|
|
|
.schedule_events = p4_pmu_schedule_events,
|
|
|
/*
|