From 8d57ad9bc4497963420f60765ee6b99eec65d9df Mon Sep 17 00:00:00 2001 From: Masamichi Takagi Date: Tue, 11 Jul 2017 18:59:19 +0900 Subject: [PATCH] pmc_start, pmc_stop: Error check on counter number --- arch/x86/kernel/perfctr.c | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/perfctr.c b/arch/x86/kernel/perfctr.c index 1b1ab99d..962a4ace 100644 --- a/arch/x86/kernel/perfctr.c +++ b/arch/x86/kernel/perfctr.c @@ -17,8 +17,26 @@ extern unsigned int *x86_march_perfmap; extern int running_on_kvm(void); +//#define PERFCTR_DEBUG +#ifdef PERFCTR_DEBUG +#define dkprintf(...) do { kprintf(__VA_ARGS__); } while (0) +#define ekprintf(...) do { kprintf(__VA_ARGS__); } while (0) +#else +#define dkprintf(...) do { } while (0) +#define ekprintf(...) do { kprintf(__VA_ARGS__); } while (0) +#endif + #define X86_CR4_PCE 0x00000100 +#define PERFCTR_CHKANDJUMP(cond, msg, err) \ + do { \ + if(cond) { \ + ekprintf("%s,"msg"\n", __FUNCTION__); \ + ret = err; \ + goto fn_fail; \ + } \ + } while(0) + int perf_counters_discovered = 0; int X86_IA32_NUM_PERF_COUNTERS = 0; unsigned long X86_IA32_PERF_COUNTERS_MASK = 0; @@ -203,9 +221,12 @@ extern void x86_march_perfctr_start(unsigned long counter_mask); int ihk_mc_perfctr_start(unsigned long counter_mask) { + int ret = 0; unsigned long value = 0; unsigned long mask = X86_IA32_PERF_COUNTERS_MASK | X86_IA32_FIXED_PERF_COUNTERS_MASK; + PERFCTR_CHKANDJUMP(counter_mask & ~mask, "counter_mask out of range", -EINVAL); + #ifdef HAVE_MARCH_PERFCTR_START x86_march_perfctr_start(counter_mask); #endif @@ -213,15 +234,20 @@ int ihk_mc_perfctr_start(unsigned long counter_mask) value = rdmsr(MSR_PERF_GLOBAL_CTRL); value |= counter_mask; wrmsr(MSR_PERF_GLOBAL_CTRL, value); - - return 0; + fn_exit: + return ret; + fn_fail: + goto fn_exit; } int ihk_mc_perfctr_stop(unsigned long counter_mask) { + int ret = 0; unsigned long value; unsigned long mask = X86_IA32_PERF_COUNTERS_MASK | X86_IA32_FIXED_PERF_COUNTERS_MASK; + PERFCTR_CHKANDJUMP(counter_mask & ~mask, "counter_mask out of range", -EINVAL); + counter_mask &= mask; value = rdmsr(MSR_PERF_GLOBAL_CTRL); value &= ~counter_mask; @@ -244,8 +270,10 @@ int ihk_mc_perfctr_stop(unsigned long counter_mask) value &= ~(0xf << 8); wrmsr(MSR_PERF_FIXED_CTRL, value); } - - return 0; + fn_exit: + return ret; + fn_fail: + goto fn_exit; } // init for fixed counter