17 #include <linux/slab.h>
18 #include <asm/ptrace.h>
27 static int counter_width = 32;
29 #define MSR_PPRO_EVENTSEL_RESERVED ((0xFFFFFFFFULL<<32)|(1ULL<<21))
33 static void ppro_shutdown(
struct op_msrs const *
const msrs)
45 static int ppro_fill_in_addresses(
struct op_msrs *
const msrs)
63 op_x86_warn_reserved(i);
73 struct op_msrs const *
const msrs)
78 if (cpu_has_arch_perfmon) {
80 eax.
full = cpuid_eax(0xa);
86 if (!(eax.split.version_id == 0 &&
90 if (counter_width < eax.split.bit_width)
91 counter_width = eax.split.bit_width;
101 op_x86_warn_in_use(i);
103 wrmsrl(msrs->
controls[i].addr, val);
115 wrmsrl(msrs->
counters[i].addr, -reset_value[i]);
116 rdmsrl(msrs->
controls[i].addr, val);
119 wrmsrl(msrs->
controls[i].addr, val);
127 static int ppro_check_ctrs(
struct pt_regs *
const regs,
128 struct op_msrs const *
const msrs)
136 rdmsrl(msrs->
counters[i].addr, val);
137 if (val & (1ULL << (counter_width - 1)))
140 wrmsrl(msrs->
counters[i].addr, -reset_value[i]);
158 static void ppro_start(
struct op_msrs const *
const msrs)
164 if (reset_value[i]) {
165 rdmsrl(msrs->
controls[i].addr, val);
167 wrmsrl(msrs->
controls[i].addr, val);
173 static void ppro_stop(
struct op_msrs const *
const msrs)
181 rdmsrl(msrs->
controls[i].addr, val);
183 wrmsrl(msrs->
controls[i].addr, val);
191 .fill_in_addresses = &ppro_fill_in_addresses,
192 .setup_ctrs = &ppro_setup_ctrs,
193 .check_ctrs = &ppro_check_ctrs,
194 .start = &ppro_start,
196 .shutdown = &ppro_shutdown
208 static void arch_perfmon_setup_counters(
void)
212 eax.
full = cpuid_eax(0xa);
217 eax.split.version_id = 2;
218 eax.split.num_counters = 2;
219 eax.split.bit_width = 40;
230 arch_perfmon_setup_counters();
236 .init = &arch_perfmon_init,
238 .fill_in_addresses = &ppro_fill_in_addresses,
240 .setup_ctrs = &ppro_setup_ctrs,
241 .check_ctrs = &ppro_check_ctrs,
242 .start = &ppro_start,
244 .shutdown = &ppro_shutdown