From 866567034147e2fa851067a80b6ff41e9764f6d3 Mon Sep 17 00:00:00 2001 From: Wei Li Date: Mon, 25 Nov 2019 10:58:16 +0800 Subject: [PATCH] arm64: perf: add support for cap_user_time_zero hulk inclusion category: feature bugzilla: 18657 CVE: NA ------------------------------------------- Add support for cap_user_time_zero on arm64 to enable the converting between perf time and tsc in perf tool. Signed-off-by: Wei Li Reviewed-by: Xuefeng Wang Reviewed-by: Tan Xiaojun Signed-off-by: Yang Yingliang --- arch/arm64/kernel/perf_event.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index a6fb347e27af..da62116a0b26 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -29,6 +29,7 @@ #include #include #include +#include /* * ARMv8 PMUv3 Performance Events handling code. @@ -1417,11 +1418,22 @@ static int __init armv8_pmu_driver_init(void) } device_initcall(armv8_pmu_driver_init) +static u64 cyc_to_ns(u64 cyc, u16 time_shift, u32 time_mult) +{ + u64 quot, rem; + + quot = cyc >> time_shift; + rem = cyc & (((u64)1 << time_shift) - 1); + return quot * time_mult + + ((rem * time_mult) >> time_shift); +} + void arch_perf_update_userpage(struct perf_event *event, struct perf_event_mmap_page *userpg, u64 now) { u32 freq; u32 shift; + u64 offset; /* * Internal timekeeping for enabled/running/stopped times @@ -1444,4 +1456,16 @@ void arch_perf_update_userpage(struct perf_event *event, } userpg->time_shift = (u16)shift; userpg->time_offset = -now; + + offset = local_clock() - cyc_to_ns(arch_timer_read_counter(), + userpg->time_shift, userpg->time_mult); + + /* + * cap_user_time_zero doesn't make sense when we're using a different + * time base for the records. + */ + if (!event->attr.use_clockid) { + userpg->cap_user_time_zero = 1; + userpg->time_zero = offset; + } } -- GitLab