Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / tools / perf / arch / x86 / util / tsc.c
diff --git a/kernel/tools/perf/arch/x86/util/tsc.c b/kernel/tools/perf/arch/x86/util/tsc.c
new file mode 100644 (file)
index 0000000..fd28684
--- /dev/null
@@ -0,0 +1,48 @@
+#include <stdbool.h>
+#include <errno.h>
+
+#include <linux/perf_event.h>
+
+#include "../../perf.h"
+#include <linux/types.h>
+#include "../../util/debug.h"
+#include "../../util/tsc.h"
+#include "tsc.h"
+
+int perf_read_tsc_conversion(const struct perf_event_mmap_page *pc,
+                            struct perf_tsc_conversion *tc)
+{
+       bool cap_user_time_zero;
+       u32 seq;
+       int i = 0;
+
+       while (1) {
+               seq = pc->lock;
+               rmb();
+               tc->time_mult = pc->time_mult;
+               tc->time_shift = pc->time_shift;
+               tc->time_zero = pc->time_zero;
+               cap_user_time_zero = pc->cap_user_time_zero;
+               rmb();
+               if (pc->lock == seq && !(seq & 1))
+                       break;
+               if (++i > 10000) {
+                       pr_debug("failed to get perf_event_mmap_page lock\n");
+                       return -EINVAL;
+               }
+       }
+
+       if (!cap_user_time_zero)
+               return -EOPNOTSUPP;
+
+       return 0;
+}
+
+u64 rdtsc(void)
+{
+       unsigned int low, high;
+
+       asm volatile("rdtsc" : "=a" (low), "=d" (high));
+
+       return low | ((u64)high) << 32;
+}