diff options
-rw-r--r-- | arch/x86/kernel/tsc.c | 11 | ||||
-rw-r--r-- | include/uapi/linux/perf_event.h | 4 |
2 files changed, 13 insertions, 2 deletions
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 69b84a26ea17..c7c4d9c51e99 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c | |||
@@ -259,6 +259,17 @@ static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu) | |||
259 | clocks_calc_mult_shift(&data->cyc2ns_mul, &data->cyc2ns_shift, cpu_khz, | 259 | clocks_calc_mult_shift(&data->cyc2ns_mul, &data->cyc2ns_shift, cpu_khz, |
260 | NSEC_PER_MSEC, 0); | 260 | NSEC_PER_MSEC, 0); |
261 | 261 | ||
262 | /* | ||
263 | * cyc2ns_shift is exported via arch_perf_update_userpage() where it is | ||
264 | * not expected to be greater than 31 due to the original published | ||
265 | * conversion algorithm shifting a 32-bit value (now specifies a 64-bit | ||
266 | * value) - refer perf_event_mmap_page documentation in perf_event.h. | ||
267 | */ | ||
268 | if (data->cyc2ns_shift == 32) { | ||
269 | data->cyc2ns_shift = 31; | ||
270 | data->cyc2ns_mul >>= 1; | ||
271 | } | ||
272 | |||
262 | data->cyc2ns_offset = ns_now - | 273 | data->cyc2ns_offset = ns_now - |
263 | mul_u64_u32_shr(tsc_now, data->cyc2ns_mul, data->cyc2ns_shift); | 274 | mul_u64_u32_shr(tsc_now, data->cyc2ns_mul, data->cyc2ns_shift); |
264 | 275 | ||
diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h index 2881145cda86..6c72e72e975c 100644 --- a/include/uapi/linux/perf_event.h +++ b/include/uapi/linux/perf_event.h | |||
@@ -476,7 +476,7 @@ struct perf_event_mmap_page { | |||
476 | * u64 delta; | 476 | * u64 delta; |
477 | * | 477 | * |
478 | * quot = (cyc >> time_shift); | 478 | * quot = (cyc >> time_shift); |
479 | * rem = cyc & ((1 << time_shift) - 1); | 479 | * rem = cyc & (((u64)1 << time_shift) - 1); |
480 | * delta = time_offset + quot * time_mult + | 480 | * delta = time_offset + quot * time_mult + |
481 | * ((rem * time_mult) >> time_shift); | 481 | * ((rem * time_mult) >> time_shift); |
482 | * | 482 | * |
@@ -507,7 +507,7 @@ struct perf_event_mmap_page { | |||
507 | * And vice versa: | 507 | * And vice versa: |
508 | * | 508 | * |
509 | * quot = cyc >> time_shift; | 509 | * quot = cyc >> time_shift; |
510 | * rem = cyc & ((1 << time_shift) - 1); | 510 | * rem = cyc & (((u64)1 << time_shift) - 1); |
511 | * timestamp = time_zero + quot * time_mult + | 511 | * timestamp = time_zero + quot * time_mult + |
512 | * ((rem * time_mult) >> time_shift); | 512 | * ((rem * time_mult) >> time_shift); |
513 | */ | 513 | */ |