msr.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. #include <linux/perf_event.h>
  2. #include <linux/nospec.h>
  3. #include <asm/intel-family.h>
  4. enum perf_msr_id {
  5. PERF_MSR_TSC = 0,
  6. PERF_MSR_APERF = 1,
  7. PERF_MSR_MPERF = 2,
  8. PERF_MSR_PPERF = 3,
  9. PERF_MSR_SMI = 4,
  10. PERF_MSR_PTSC = 5,
  11. PERF_MSR_IRPERF = 6,
  12. PERF_MSR_EVENT_MAX,
  13. };
  14. static bool test_aperfmperf(int idx)
  15. {
  16. return boot_cpu_has(X86_FEATURE_APERFMPERF);
  17. }
  18. static bool test_ptsc(int idx)
  19. {
  20. return boot_cpu_has(X86_FEATURE_PTSC);
  21. }
  22. static bool test_irperf(int idx)
  23. {
  24. return boot_cpu_has(X86_FEATURE_IRPERF);
  25. }
  26. static bool test_intel(int idx)
  27. {
  28. if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ||
  29. boot_cpu_data.x86 != 6)
  30. return false;
  31. switch (boot_cpu_data.x86_model) {
  32. case INTEL_FAM6_NEHALEM:
  33. case INTEL_FAM6_NEHALEM_G:
  34. case INTEL_FAM6_NEHALEM_EP:
  35. case INTEL_FAM6_NEHALEM_EX:
  36. case INTEL_FAM6_WESTMERE:
  37. case INTEL_FAM6_WESTMERE_EP:
  38. case INTEL_FAM6_WESTMERE_EX:
  39. case INTEL_FAM6_SANDYBRIDGE:
  40. case INTEL_FAM6_SANDYBRIDGE_X:
  41. case INTEL_FAM6_IVYBRIDGE:
  42. case INTEL_FAM6_IVYBRIDGE_X:
  43. case INTEL_FAM6_HASWELL_CORE:
  44. case INTEL_FAM6_HASWELL_X:
  45. case INTEL_FAM6_HASWELL_ULT:
  46. case INTEL_FAM6_HASWELL_GT3E:
  47. case INTEL_FAM6_BROADWELL_CORE:
  48. case INTEL_FAM6_BROADWELL_XEON_D:
  49. case INTEL_FAM6_BROADWELL_GT3E:
  50. case INTEL_FAM6_BROADWELL_X:
  51. case INTEL_FAM6_ATOM_SILVERMONT1:
  52. case INTEL_FAM6_ATOM_SILVERMONT2:
  53. case INTEL_FAM6_ATOM_AIRMONT:
  54. if (idx == PERF_MSR_SMI)
  55. return true;
  56. break;
  57. case INTEL_FAM6_SKYLAKE_MOBILE:
  58. case INTEL_FAM6_SKYLAKE_DESKTOP:
  59. case INTEL_FAM6_SKYLAKE_X:
  60. case INTEL_FAM6_KABYLAKE_MOBILE:
  61. case INTEL_FAM6_KABYLAKE_DESKTOP:
  62. if (idx == PERF_MSR_SMI || idx == PERF_MSR_PPERF)
  63. return true;
  64. break;
  65. }
  66. return false;
  67. }
  68. struct perf_msr {
  69. u64 msr;
  70. struct perf_pmu_events_attr *attr;
  71. bool (*test)(int idx);
  72. };
  73. PMU_EVENT_ATTR_STRING(tsc, evattr_tsc, "event=0x00");
  74. PMU_EVENT_ATTR_STRING(aperf, evattr_aperf, "event=0x01");
  75. PMU_EVENT_ATTR_STRING(mperf, evattr_mperf, "event=0x02");
  76. PMU_EVENT_ATTR_STRING(pperf, evattr_pperf, "event=0x03");
  77. PMU_EVENT_ATTR_STRING(smi, evattr_smi, "event=0x04");
  78. PMU_EVENT_ATTR_STRING(ptsc, evattr_ptsc, "event=0x05");
  79. PMU_EVENT_ATTR_STRING(irperf, evattr_irperf, "event=0x06");
  80. static struct perf_msr msr[] = {
  81. [PERF_MSR_TSC] = { 0, &evattr_tsc, NULL, },
  82. [PERF_MSR_APERF] = { MSR_IA32_APERF, &evattr_aperf, test_aperfmperf, },
  83. [PERF_MSR_MPERF] = { MSR_IA32_MPERF, &evattr_mperf, test_aperfmperf, },
  84. [PERF_MSR_PPERF] = { MSR_PPERF, &evattr_pperf, test_intel, },
  85. [PERF_MSR_SMI] = { MSR_SMI_COUNT, &evattr_smi, test_intel, },
  86. [PERF_MSR_PTSC] = { MSR_F15H_PTSC, &evattr_ptsc, test_ptsc, },
  87. [PERF_MSR_IRPERF] = { MSR_F17H_IRPERF, &evattr_irperf, test_irperf, },
  88. };
  89. static struct attribute *events_attrs[PERF_MSR_EVENT_MAX + 1] = {
  90. NULL,
  91. };
  92. static struct attribute_group events_attr_group = {
  93. .name = "events",
  94. .attrs = events_attrs,
  95. };
  96. PMU_FORMAT_ATTR(event, "config:0-63");
  97. static struct attribute *format_attrs[] = {
  98. &format_attr_event.attr,
  99. NULL,
  100. };
  101. static struct attribute_group format_attr_group = {
  102. .name = "format",
  103. .attrs = format_attrs,
  104. };
  105. static const struct attribute_group *attr_groups[] = {
  106. &events_attr_group,
  107. &format_attr_group,
  108. NULL,
  109. };
  110. static int msr_event_init(struct perf_event *event)
  111. {
  112. u64 cfg = event->attr.config;
  113. if (event->attr.type != event->pmu->type)
  114. return -ENOENT;
  115. /* unsupported modes and filters */
  116. if (event->attr.exclude_user ||
  117. event->attr.exclude_kernel ||
  118. event->attr.exclude_hv ||
  119. event->attr.exclude_idle ||
  120. event->attr.exclude_host ||
  121. event->attr.exclude_guest ||
  122. event->attr.sample_period) /* no sampling */
  123. return -EINVAL;
  124. if (cfg >= PERF_MSR_EVENT_MAX)
  125. return -EINVAL;
  126. cfg = array_index_nospec((unsigned long)cfg, PERF_MSR_EVENT_MAX);
  127. if (!msr[cfg].attr)
  128. return -EINVAL;
  129. event->hw.idx = -1;
  130. event->hw.event_base = msr[cfg].msr;
  131. event->hw.config = cfg;
  132. return 0;
  133. }
  134. static inline u64 msr_read_counter(struct perf_event *event)
  135. {
  136. u64 now;
  137. if (event->hw.event_base)
  138. rdmsrl(event->hw.event_base, now);
  139. else
  140. rdtscll(now);
  141. return now;
  142. }
  143. static void msr_event_update(struct perf_event *event)
  144. {
  145. u64 prev, now;
  146. s64 delta;
  147. /* Careful, an NMI might modify the previous event value. */
  148. again:
  149. prev = local64_read(&event->hw.prev_count);
  150. now = msr_read_counter(event);
  151. if (local64_cmpxchg(&event->hw.prev_count, prev, now) != prev)
  152. goto again;
  153. delta = now - prev;
  154. if (unlikely(event->hw.event_base == MSR_SMI_COUNT))
  155. delta = sign_extend64(delta, 31);
  156. local64_add(delta, &event->count);
  157. }
  158. static void msr_event_start(struct perf_event *event, int flags)
  159. {
  160. u64 now;
  161. now = msr_read_counter(event);
  162. local64_set(&event->hw.prev_count, now);
  163. }
  164. static void msr_event_stop(struct perf_event *event, int flags)
  165. {
  166. msr_event_update(event);
  167. }
  168. static void msr_event_del(struct perf_event *event, int flags)
  169. {
  170. msr_event_stop(event, PERF_EF_UPDATE);
  171. }
  172. static int msr_event_add(struct perf_event *event, int flags)
  173. {
  174. if (flags & PERF_EF_START)
  175. msr_event_start(event, flags);
  176. return 0;
  177. }
  178. static struct pmu pmu_msr = {
  179. .task_ctx_nr = perf_sw_context,
  180. .attr_groups = attr_groups,
  181. .event_init = msr_event_init,
  182. .add = msr_event_add,
  183. .del = msr_event_del,
  184. .start = msr_event_start,
  185. .stop = msr_event_stop,
  186. .read = msr_event_update,
  187. .capabilities = PERF_PMU_CAP_NO_INTERRUPT,
  188. };
  189. static int __init msr_init(void)
  190. {
  191. int i, j = 0;
  192. if (!boot_cpu_has(X86_FEATURE_TSC)) {
  193. pr_cont("no MSR PMU driver.\n");
  194. return 0;
  195. }
  196. /* Probe the MSRs. */
  197. for (i = PERF_MSR_TSC + 1; i < PERF_MSR_EVENT_MAX; i++) {
  198. u64 val;
  199. /*
  200. * Virt sucks arse; you cannot tell if a R/O MSR is present :/
  201. */
  202. if (!msr[i].test(i) || rdmsrl_safe(msr[i].msr, &val))
  203. msr[i].attr = NULL;
  204. }
  205. /* List remaining MSRs in the sysfs attrs. */
  206. for (i = 0; i < PERF_MSR_EVENT_MAX; i++) {
  207. if (msr[i].attr)
  208. events_attrs[j++] = &msr[i].attr->attr.attr;
  209. }
  210. events_attrs[j] = NULL;
  211. perf_pmu_register(&pmu_msr, "msr", -1);
  212. return 0;
  213. }
  214. device_initcall(msr_init);