aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/tsc.c11
-rw-r--r--include/uapi/linux/perf_event.h4
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 */