pmc_start, pmc_stop: Error check on counter number
This commit is contained in:
@@ -17,8 +17,26 @@
|
|||||||
extern unsigned int *x86_march_perfmap;
|
extern unsigned int *x86_march_perfmap;
|
||||||
extern int running_on_kvm(void);
|
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 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 perf_counters_discovered = 0;
|
||||||
int X86_IA32_NUM_PERF_COUNTERS = 0;
|
int X86_IA32_NUM_PERF_COUNTERS = 0;
|
||||||
unsigned long X86_IA32_PERF_COUNTERS_MASK = 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 ihk_mc_perfctr_start(unsigned long counter_mask)
|
||||||
{
|
{
|
||||||
|
int ret = 0;
|
||||||
unsigned long value = 0;
|
unsigned long value = 0;
|
||||||
unsigned long mask = X86_IA32_PERF_COUNTERS_MASK | X86_IA32_FIXED_PERF_COUNTERS_MASK;
|
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
|
#ifdef HAVE_MARCH_PERFCTR_START
|
||||||
x86_march_perfctr_start(counter_mask);
|
x86_march_perfctr_start(counter_mask);
|
||||||
#endif
|
#endif
|
||||||
@@ -213,15 +234,20 @@ int ihk_mc_perfctr_start(unsigned long counter_mask)
|
|||||||
value = rdmsr(MSR_PERF_GLOBAL_CTRL);
|
value = rdmsr(MSR_PERF_GLOBAL_CTRL);
|
||||||
value |= counter_mask;
|
value |= counter_mask;
|
||||||
wrmsr(MSR_PERF_GLOBAL_CTRL, value);
|
wrmsr(MSR_PERF_GLOBAL_CTRL, value);
|
||||||
|
fn_exit:
|
||||||
return 0;
|
return ret;
|
||||||
|
fn_fail:
|
||||||
|
goto fn_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ihk_mc_perfctr_stop(unsigned long counter_mask)
|
int ihk_mc_perfctr_stop(unsigned long counter_mask)
|
||||||
{
|
{
|
||||||
|
int ret = 0;
|
||||||
unsigned long value;
|
unsigned long value;
|
||||||
unsigned long mask = X86_IA32_PERF_COUNTERS_MASK | X86_IA32_FIXED_PERF_COUNTERS_MASK;
|
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;
|
counter_mask &= mask;
|
||||||
value = rdmsr(MSR_PERF_GLOBAL_CTRL);
|
value = rdmsr(MSR_PERF_GLOBAL_CTRL);
|
||||||
value &= ~counter_mask;
|
value &= ~counter_mask;
|
||||||
@@ -244,8 +270,10 @@ int ihk_mc_perfctr_stop(unsigned long counter_mask)
|
|||||||
value &= ~(0xf << 8);
|
value &= ~(0xf << 8);
|
||||||
wrmsr(MSR_PERF_FIXED_CTRL, value);
|
wrmsr(MSR_PERF_FIXED_CTRL, value);
|
||||||
}
|
}
|
||||||
|
fn_exit:
|
||||||
return 0;
|
return ret;
|
||||||
|
fn_fail:
|
||||||
|
goto fn_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// init for fixed counter
|
// init for fixed counter
|
||||||
|
|||||||
Reference in New Issue
Block a user