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