op_model_ppro.c 6.3 KB

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