1/* 2 * @file op_model_ppro.h 3 * Family 6 perfmon and architectural perfmon MSR operations 4 * 5 * @remark Copyright 2002 OProfile authors 6 * @remark Copyright 2008 Intel Corporation 7 * @remark Read the file COPYING 8 * 9 * @author John Levon 10 * @author Philippe Elie 11 * @author Graydon Hoare 12 * @author Andi Kleen 13 * @author Robert Richter <robert.richter@amd.com> 14 */ 15 16#include <linux/oprofile.h> 17#include <linux/slab.h> 18#include <asm/ptrace.h> 19#include <asm/msr.h> 20#include <asm/apic.h> 21#include <asm/nmi.h> 22 23#include "op_x86_model.h" 24#include "op_counter.h" 25 26static int num_counters = 2; 27static int counter_width = 32; 28 29#define MSR_PPRO_EVENTSEL_RESERVED ((0xFFFFFFFFULL<<32)|(1ULL<<21)) 30 31static u64 *reset_value; 32 33static void ppro_shutdown(struct op_msrs const * const msrs) 34{ 35 int i; 36 37 for (i = 0; i < num_counters; ++i) { 38 if (!msrs->counters[i].addr) 39 continue; 40 release_perfctr_nmi(MSR_P6_PERFCTR0 + i); 41 release_evntsel_nmi(MSR_P6_EVNTSEL0 + i); 42 } 43 if (reset_value) { 44 kfree(reset_value); 45 reset_value = NULL; 46 } 47} 48 49static int ppro_fill_in_addresses(struct op_msrs * const msrs) 50{ 51 int i; 52 53 for (i = 0; i < num_counters; i++) { 54 if (!reserve_perfctr_nmi(MSR_P6_PERFCTR0 + i)) 55 goto fail; 56 if (!reserve_evntsel_nmi(MSR_P6_EVNTSEL0 + i)) { 57 release_perfctr_nmi(MSR_P6_PERFCTR0 + i); 58 goto fail; 59 } 60 /* both registers must be reserved */ 61 msrs->counters[i].addr = MSR_P6_PERFCTR0 + i; 62 msrs->controls[i].addr = MSR_P6_EVNTSEL0 + i; 63 continue; 64 fail: 65 if (!counter_config[i].enabled) 66 continue; 67 op_x86_warn_reserved(i); 68 ppro_shutdown(msrs); 69 return -EBUSY; 70 } 71 72 return 0; 73} 74 75 76static void ppro_setup_ctrs(struct op_x86_model_spec const *model, 77 struct op_msrs const * const msrs) 78{ 79 u64 val; 80 int i; 81 82 if (!reset_value) { 83 reset_value = kzalloc(sizeof(reset_value[0]) * num_counters, 84 GFP_ATOMIC); 85 if (!reset_value) 86 return; 87 } 88 89 if (cpu_has_arch_perfmon) { 90 union cpuid10_eax eax; 91 eax.full = cpuid_eax(0xa); 92 93 /* 94 * For Core2 (family 6, model 15), don't reset the 95 * counter width: 96 */ 97 if (!(eax.split.version_id == 0 && 98 current_cpu_data.x86 == 6 && 99 current_cpu_data.x86_model == 15)) { 100 101 if (counter_width < eax.split.bit_width) 102 counter_width = eax.split.bit_width; 103 } 104 } 105 106 /* clear all counters */ 107 for (i = 0; i < num_counters; ++i) { 108 if (!msrs->controls[i].addr) 109 continue; 110 rdmsrl(msrs->controls[i].addr, val); 111 if (val & ARCH_PERFMON_EVENTSEL_ENABLE) 112 op_x86_warn_in_use(i); 113 val &= model->reserved; 114 wrmsrl(msrs->controls[i].addr, val); 115 /* 116 * avoid a false detection of ctr overflows in NMI * 117 * handler 118 */ 119 wrmsrl(msrs->counters[i].addr, -1LL); 120 } 121 122 /* enable active counters */ 123 for (i = 0; i < num_counters; ++i) { 124 if (counter_config[i].enabled && msrs->counters[i].addr) { 125 reset_value[i] = counter_config[i].count; 126 wrmsrl(msrs->counters[i].addr, -reset_value[i]); 127 rdmsrl(msrs->controls[i].addr, val); 128 val &= model->reserved; 129 val |= op_x86_get_ctrl(model, &counter_config[i]); 130 wrmsrl(msrs->controls[i].addr, val); 131 } else { 132 reset_value[i] = 0; 133 } 134 } 135} 136 137 138static int ppro_check_ctrs(struct pt_regs * const regs, 139 struct op_msrs const * const msrs) 140{ 141 u64 val; 142 int i; 143 144 /* 145 * This can happen if perf counters are in use when 146 * we steal the die notifier NMI. 147 */ 148 if (unlikely(!reset_value)) 149 goto out; 150 151 for (i = 0; i < num_counters; ++i) { 152 if (!reset_value[i]) 153 continue; 154 rdmsrl(msrs->counters[i].addr, val); 155 if (val & (1ULL << (counter_width - 1))) 156 continue; 157 oprofile_add_sample(regs, i); 158 wrmsrl(msrs->counters[i].addr, -reset_value[i]); 159 } 160 161out: 162 /* Only P6 based Pentium M need to re-unmask the apic vector but it 163 * doesn't hurt other P6 variant */ 164 apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED); 165 166 /* We can't work out if we really handled an interrupt. We 167 * might have caught a *second* counter just after overflowing 168 * the interrupt for this counter then arrives 169 * and we don't find a counter that's overflowed, so we 170 * would return 0 and get dazed + confused. Instead we always 171 * assume we found an overflow. This sucks. 172 */ 173 return 1; 174} 175 176 177static void ppro_start(struct op_msrs const * const msrs) 178{ 179 u64 val; 180 int i; 181 182 if (!reset_value) 183 return; 184 for (i = 0; i < num_counters; ++i) { 185 if (reset_value[i]) { 186 rdmsrl(msrs->controls[i].addr, val); 187 val |= ARCH_PERFMON_EVENTSEL_ENABLE; 188 wrmsrl(msrs->controls[i].addr, val); 189 } 190 } 191} 192 193 194static void ppro_stop(struct op_msrs const * const msrs) 195{ 196 u64 val; 197 int i; 198 199 if (!reset_value) 200 return; 201 for (i = 0; i < num_counters; ++i) { 202 if (!reset_value[i]) 203 continue; 204 rdmsrl(msrs->controls[i].addr, val); 205 val &= ~ARCH_PERFMON_EVENTSEL_ENABLE; 206 wrmsrl(msrs->controls[i].addr, val); 207 } 208} 209 210struct op_x86_model_spec op_ppro_spec = { 211 .num_counters = 2, 212 .num_controls = 2, 213 .reserved = MSR_PPRO_EVENTSEL_RESERVED, 214 .fill_in_addresses = &ppro_fill_in_addresses, 215 .setup_ctrs = &ppro_setup_ctrs, 216 .check_ctrs = &ppro_check_ctrs, 217 .start = &ppro_start, 218 .stop = &ppro_stop, 219 .shutdown = &ppro_shutdown 220}; 221 222/* 223 * Architectural performance monitoring. 224 * 225 * Newer Intel CPUs (Core1+) have support for architectural 226 * events described in CPUID 0xA. See the IA32 SDM Vol3b.18 for details. 227 * The advantage of this is that it can be done without knowing about 228 * the specific CPU. 229 */ 230 231static void arch_perfmon_setup_counters(void) 232{ 233 union cpuid10_eax eax; 234 235 eax.full = cpuid_eax(0xa); 236 237 if (eax.split.version_id == 0 && current_cpu_data.x86 == 6 && 238 current_cpu_data.x86_model == 15) { 239 eax.split.version_id = 2; 240 eax.split.num_counters = 2; 241 eax.split.bit_width = 40; 242 } 243 244 num_counters = eax.split.num_counters; 245 246 op_arch_perfmon_spec.num_counters = num_counters; 247 op_arch_perfmon_spec.num_controls = num_counters; 248} 249 250static int arch_perfmon_init(struct oprofile_operations *ignore) 251{ 252 arch_perfmon_setup_counters(); 253 return 0; 254} 255 256struct op_x86_model_spec op_arch_perfmon_spec = { 257 .reserved = MSR_PPRO_EVENTSEL_RESERVED, 258 .init = &arch_perfmon_init, 259 /* num_counters/num_controls filled in at runtime */ 260 .fill_in_addresses = &ppro_fill_in_addresses, 261 /* user space does the cpuid check for available events */ 262 .setup_ctrs = &ppro_setup_ctrs, 263 .check_ctrs = &ppro_check_ctrs, 264 .start = &ppro_start, 265 .stop = &ppro_stop, 266 .shutdown = &ppro_shutdown 267}; 268