diff options
Diffstat (limited to 'arch/x86/kernel/cpu/perf_event_p4.c')
| -rw-r--r-- | arch/x86/kernel/cpu/perf_event_p4.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index f7a0993c1e7..ff751a9f182 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c | |||
| @@ -770,9 +770,14 @@ static inline int p4_pmu_clear_cccr_ovf(struct hw_perf_event *hwc) | |||
| 770 | return 1; | 770 | return 1; |
| 771 | } | 771 | } |
| 772 | 772 | ||
| 773 | /* it might be unflagged overflow */ | 773 | /* |
| 774 | rdmsrl(hwc->event_base + hwc->idx, v); | 774 | * In some circumstances the overflow might issue an NMI but did |
| 775 | if (!(v & ARCH_P4_CNTRVAL_MASK)) | 775 | * not set P4_CCCR_OVF bit. Because a counter holds a negative value |
| 776 | * we simply check for high bit being set, if it's cleared it means | ||
| 777 | * the counter has reached zero value and continued counting before | ||
| 778 | * real NMI signal was received: | ||
| 779 | */ | ||
| 780 | if (!(v & ARCH_P4_UNFLAGGED_BIT)) | ||
| 776 | return 1; | 781 | return 1; |
| 777 | 782 | ||
| 778 | return 0; | 783 | return 0; |
