Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
op_model_ppro.c
Go to the documentation of this file.
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 <[email protected]>
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 
26 static int num_counters = 2;
27 static int counter_width = 32;
28 
29 #define MSR_PPRO_EVENTSEL_RESERVED ((0xFFFFFFFFULL<<32)|(1ULL<<21))
30 
31 static u64 reset_value[OP_MAX_COUNTER];
32 
33 static 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;
42  }
43 }
44 
45 static int ppro_fill_in_addresses(struct op_msrs * const msrs)
46 {
47  int i;
48 
49  for (i = 0; i < num_counters; i++) {
51  goto fail;
54  goto fail;
55  }
56  /* both registers must be reserved */
57  msrs->counters[i].addr = MSR_P6_PERFCTR0 + i;
58  msrs->controls[i].addr = MSR_P6_EVNTSEL0 + i;
59  continue;
60  fail:
61  if (!counter_config[i].enabled)
62  continue;
63  op_x86_warn_reserved(i);
64  ppro_shutdown(msrs);
65  return -EBUSY;
66  }
67 
68  return 0;
69 }
70 
71 
72 static void ppro_setup_ctrs(struct op_x86_model_spec const *model,
73  struct op_msrs const * const msrs)
74 {
75  u64 val;
76  int i;
77 
78  if (cpu_has_arch_perfmon) {
79  union cpuid10_eax eax;
80  eax.full = cpuid_eax(0xa);
81 
82  /*
83  * For Core2 (family 6, model 15), don't reset the
84  * counter width:
85  */
86  if (!(eax.split.version_id == 0 &&
87  __this_cpu_read(cpu_info.x86) == 6 &&
88  __this_cpu_read(cpu_info.x86_model) == 15)) {
89 
90  if (counter_width < eax.split.bit_width)
91  counter_width = eax.split.bit_width;
92  }
93  }
94 
95  /* clear all counters */
96  for (i = 0; i < num_counters; ++i) {
97  if (!msrs->controls[i].addr)
98  continue;
99  rdmsrl(msrs->controls[i].addr, val);
101  op_x86_warn_in_use(i);
102  val &= model->reserved;
103  wrmsrl(msrs->controls[i].addr, val);
104  /*
105  * avoid a false detection of ctr overflows in NMI *
106  * handler
107  */
108  wrmsrl(msrs->counters[i].addr, -1LL);
109  }
110 
111  /* enable active counters */
112  for (i = 0; i < num_counters; ++i) {
113  if (counter_config[i].enabled && msrs->counters[i].addr) {
114  reset_value[i] = counter_config[i].count;
115  wrmsrl(msrs->counters[i].addr, -reset_value[i]);
116  rdmsrl(msrs->controls[i].addr, val);
117  val &= model->reserved;
118  val |= op_x86_get_ctrl(model, &counter_config[i]);
119  wrmsrl(msrs->controls[i].addr, val);
120  } else {
121  reset_value[i] = 0;
122  }
123  }
124 }
125 
126 
127 static int ppro_check_ctrs(struct pt_regs * const regs,
128  struct op_msrs const * const msrs)
129 {
130  u64 val;
131  int i;
132 
133  for (i = 0; i < num_counters; ++i) {
134  if (!reset_value[i])
135  continue;
136  rdmsrl(msrs->counters[i].addr, val);
137  if (val & (1ULL << (counter_width - 1)))
138  continue;
139  oprofile_add_sample(regs, i);
140  wrmsrl(msrs->counters[i].addr, -reset_value[i]);
141  }
142 
143  /* Only P6 based Pentium M need to re-unmask the apic vector but it
144  * doesn't hurt other P6 variant */
145  apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED);
146 
147  /* We can't work out if we really handled an interrupt. We
148  * might have caught a *second* counter just after overflowing
149  * the interrupt for this counter then arrives
150  * and we don't find a counter that's overflowed, so we
151  * would return 0 and get dazed + confused. Instead we always
152  * assume we found an overflow. This sucks.
153  */
154  return 1;
155 }
156 
157 
158 static void ppro_start(struct op_msrs const * const msrs)
159 {
160  u64 val;
161  int i;
162 
163  for (i = 0; i < num_counters; ++i) {
164  if (reset_value[i]) {
165  rdmsrl(msrs->controls[i].addr, val);
167  wrmsrl(msrs->controls[i].addr, val);
168  }
169  }
170 }
171 
172 
173 static void ppro_stop(struct op_msrs const * const msrs)
174 {
175  u64 val;
176  int i;
177 
178  for (i = 0; i < num_counters; ++i) {
179  if (!reset_value[i])
180  continue;
181  rdmsrl(msrs->controls[i].addr, val);
183  wrmsrl(msrs->controls[i].addr, val);
184  }
185 }
186 
188  .num_counters = 2,
189  .num_controls = 2,
190  .reserved = MSR_PPRO_EVENTSEL_RESERVED,
191  .fill_in_addresses = &ppro_fill_in_addresses,
192  .setup_ctrs = &ppro_setup_ctrs,
193  .check_ctrs = &ppro_check_ctrs,
194  .start = &ppro_start,
195  .stop = &ppro_stop,
196  .shutdown = &ppro_shutdown
197 };
198 
199 /*
200  * Architectural performance monitoring.
201  *
202  * Newer Intel CPUs (Core1+) have support for architectural
203  * events described in CPUID 0xA. See the IA32 SDM Vol3b.18 for details.
204  * The advantage of this is that it can be done without knowing about
205  * the specific CPU.
206  */
207 
208 static void arch_perfmon_setup_counters(void)
209 {
210  union cpuid10_eax eax;
211 
212  eax.full = cpuid_eax(0xa);
213 
214  /* Workaround for BIOS bugs in 6/15. Taken from perfmon2 */
215  if (eax.split.version_id == 0 && __this_cpu_read(cpu_info.x86) == 6 &&
216  __this_cpu_read(cpu_info.x86_model) == 15) {
217  eax.split.version_id = 2;
218  eax.split.num_counters = 2;
219  eax.split.bit_width = 40;
220  }
221 
222  num_counters = min((int)eax.split.num_counters, OP_MAX_COUNTER);
223 
224  op_arch_perfmon_spec.num_counters = num_counters;
225  op_arch_perfmon_spec.num_controls = num_counters;
226 }
227 
228 static int arch_perfmon_init(struct oprofile_operations *ignore)
229 {
230  arch_perfmon_setup_counters();
231  return 0;
232 }
233 
235  .reserved = MSR_PPRO_EVENTSEL_RESERVED,
236  .init = &arch_perfmon_init,
237  /* num_counters/num_controls filled in at runtime */
238  .fill_in_addresses = &ppro_fill_in_addresses,
239  /* user space does the cpuid check for available events */
240  .setup_ctrs = &ppro_setup_ctrs,
241  .check_ctrs = &ppro_check_ctrs,
242  .start = &ppro_start,
243  .stop = &ppro_stop,
244  .shutdown = &ppro_shutdown
245 };