1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/perf_event.h>
3 #include <linux/sysfs.h>
4 #include <linux/nospec.h>
5 #include <asm/cpu_device_id.h>
20 static bool test_aperfmperf(int idx
, void *data
)
22 return boot_cpu_has(X86_FEATURE_APERFMPERF
);
25 static bool test_ptsc(int idx
, void *data
)
27 return boot_cpu_has(X86_FEATURE_PTSC
);
30 static bool test_irperf(int idx
, void *data
)
32 return boot_cpu_has(X86_FEATURE_IRPERF
);
35 static bool test_therm_status(int idx
, void *data
)
37 return boot_cpu_has(X86_FEATURE_DTHERM
);
40 static bool test_intel(int idx
, void *data
)
42 if (boot_cpu_data
.x86_vendor
!= X86_VENDOR_INTEL
||
43 boot_cpu_data
.x86
!= 6)
46 switch (boot_cpu_data
.x86_vfm
) {
49 case INTEL_NEHALEM_EP
:
50 case INTEL_NEHALEM_EX
:
53 case INTEL_WESTMERE_EP
:
54 case INTEL_WESTMERE_EX
:
56 case INTEL_SANDYBRIDGE
:
57 case INTEL_SANDYBRIDGE_X
:
60 case INTEL_IVYBRIDGE_X
:
68 case INTEL_BROADWELL_D
:
69 case INTEL_BROADWELL_G
:
70 case INTEL_BROADWELL_X
:
71 case INTEL_SAPPHIRERAPIDS_X
:
72 case INTEL_EMERALDRAPIDS_X
:
73 case INTEL_GRANITERAPIDS_X
:
74 case INTEL_GRANITERAPIDS_D
:
76 case INTEL_ATOM_SILVERMONT
:
77 case INTEL_ATOM_SILVERMONT_D
:
78 case INTEL_ATOM_AIRMONT
:
80 case INTEL_ATOM_GOLDMONT
:
81 case INTEL_ATOM_GOLDMONT_D
:
82 case INTEL_ATOM_GOLDMONT_PLUS
:
83 case INTEL_ATOM_TREMONT_D
:
84 case INTEL_ATOM_TREMONT
:
85 case INTEL_ATOM_TREMONT_L
:
87 case INTEL_XEON_PHI_KNL
:
88 case INTEL_XEON_PHI_KNM
:
89 if (idx
== PERF_MSR_SMI
)
96 case INTEL_KABYLAKE_L
:
98 case INTEL_COMETLAKE_L
:
100 case INTEL_ICELAKE_L
:
102 case INTEL_ICELAKE_X
:
103 case INTEL_ICELAKE_D
:
104 case INTEL_TIGERLAKE_L
:
105 case INTEL_TIGERLAKE
:
106 case INTEL_ROCKETLAKE
:
107 case INTEL_ALDERLAKE
:
108 case INTEL_ALDERLAKE_L
:
109 case INTEL_ATOM_GRACEMONT
:
110 case INTEL_RAPTORLAKE
:
111 case INTEL_RAPTORLAKE_P
:
112 case INTEL_RAPTORLAKE_S
:
113 case INTEL_METEORLAKE
:
114 case INTEL_METEORLAKE_L
:
115 if (idx
== PERF_MSR_SMI
|| idx
== PERF_MSR_PPERF
)
123 PMU_EVENT_ATTR_STRING(tsc
, attr_tsc
, "event=0x00" );
124 PMU_EVENT_ATTR_STRING(aperf
, attr_aperf
, "event=0x01" );
125 PMU_EVENT_ATTR_STRING(mperf
, attr_mperf
, "event=0x02" );
126 PMU_EVENT_ATTR_STRING(pperf
, attr_pperf
, "event=0x03" );
127 PMU_EVENT_ATTR_STRING(smi
, attr_smi
, "event=0x04" );
128 PMU_EVENT_ATTR_STRING(ptsc
, attr_ptsc
, "event=0x05" );
129 PMU_EVENT_ATTR_STRING(irperf
, attr_irperf
, "event=0x06" );
130 PMU_EVENT_ATTR_STRING(cpu_thermal_margin
, attr_therm
, "event=0x07" );
131 PMU_EVENT_ATTR_STRING(cpu_thermal_margin
.snapshot
, attr_therm_snap
, "1" );
132 PMU_EVENT_ATTR_STRING(cpu_thermal_margin
.unit
, attr_therm_unit
, "C" );
134 static unsigned long msr_mask
;
136 PMU_EVENT_GROUP(events
, aperf
);
137 PMU_EVENT_GROUP(events
, mperf
);
138 PMU_EVENT_GROUP(events
, pperf
);
139 PMU_EVENT_GROUP(events
, smi
);
140 PMU_EVENT_GROUP(events
, ptsc
);
141 PMU_EVENT_GROUP(events
, irperf
);
143 static struct attribute
*attrs_therm
[] = {
144 &attr_therm
.attr
.attr
,
145 &attr_therm_snap
.attr
.attr
,
146 &attr_therm_unit
.attr
.attr
,
150 static struct attribute_group group_therm
= {
152 .attrs
= attrs_therm
,
155 static struct perf_msr msr
[] = {
156 [PERF_MSR_TSC
] = { .no_check
= true, },
157 [PERF_MSR_APERF
] = { MSR_IA32_APERF
, &group_aperf
, test_aperfmperf
, },
158 [PERF_MSR_MPERF
] = { MSR_IA32_MPERF
, &group_mperf
, test_aperfmperf
, },
159 [PERF_MSR_PPERF
] = { MSR_PPERF
, &group_pperf
, test_intel
, },
160 [PERF_MSR_SMI
] = { MSR_SMI_COUNT
, &group_smi
, test_intel
, },
161 [PERF_MSR_PTSC
] = { MSR_F15H_PTSC
, &group_ptsc
, test_ptsc
, },
162 [PERF_MSR_IRPERF
] = { MSR_F17H_IRPERF
, &group_irperf
, test_irperf
, },
163 [PERF_MSR_THERM
] = { MSR_IA32_THERM_STATUS
, &group_therm
, test_therm_status
, },
166 static struct attribute
*events_attrs
[] = {
171 static struct attribute_group events_attr_group
= {
173 .attrs
= events_attrs
,
176 PMU_FORMAT_ATTR(event
, "config:0-63");
177 static struct attribute
*format_attrs
[] = {
178 &format_attr_event
.attr
,
181 static struct attribute_group format_attr_group
= {
183 .attrs
= format_attrs
,
186 static const struct attribute_group
*attr_groups
[] = {
192 static const struct attribute_group
*attr_update
[] = {
203 static int msr_event_init(struct perf_event
*event
)
205 u64 cfg
= event
->attr
.config
;
207 if (event
->attr
.type
!= event
->pmu
->type
)
210 /* unsupported modes and filters */
211 if (event
->attr
.sample_period
) /* no sampling */
214 if (cfg
>= PERF_MSR_EVENT_MAX
)
217 cfg
= array_index_nospec((unsigned long)cfg
, PERF_MSR_EVENT_MAX
);
219 if (!(msr_mask
& (1 << cfg
)))
223 event
->hw
.event_base
= msr
[cfg
].msr
;
224 event
->hw
.config
= cfg
;
229 static inline u64
msr_read_counter(struct perf_event
*event
)
233 if (event
->hw
.event_base
)
234 rdmsrl(event
->hw
.event_base
, now
);
236 now
= rdtsc_ordered();
241 static void msr_event_update(struct perf_event
*event
)
246 /* Careful, an NMI might modify the previous event value: */
247 prev
= local64_read(&event
->hw
.prev_count
);
249 now
= msr_read_counter(event
);
250 } while (!local64_try_cmpxchg(&event
->hw
.prev_count
, &prev
, now
));
253 if (unlikely(event
->hw
.event_base
== MSR_SMI_COUNT
)) {
254 delta
= sign_extend64(delta
, 31);
255 local64_add(delta
, &event
->count
);
256 } else if (unlikely(event
->hw
.event_base
== MSR_IA32_THERM_STATUS
)) {
257 /* If valid, extract digital readout, otherwise set to -1: */
258 now
= now
& (1ULL << 31) ? (now
>> 16) & 0x3f : -1;
259 local64_set(&event
->count
, now
);
261 local64_add(delta
, &event
->count
);
265 static void msr_event_start(struct perf_event
*event
, int flags
)
267 u64 now
= msr_read_counter(event
);
269 local64_set(&event
->hw
.prev_count
, now
);
272 static void msr_event_stop(struct perf_event
*event
, int flags
)
274 msr_event_update(event
);
277 static void msr_event_del(struct perf_event
*event
, int flags
)
279 msr_event_stop(event
, PERF_EF_UPDATE
);
282 static int msr_event_add(struct perf_event
*event
, int flags
)
284 if (flags
& PERF_EF_START
)
285 msr_event_start(event
, flags
);
290 static struct pmu pmu_msr
= {
291 .task_ctx_nr
= perf_sw_context
,
292 .attr_groups
= attr_groups
,
293 .event_init
= msr_event_init
,
294 .add
= msr_event_add
,
295 .del
= msr_event_del
,
296 .start
= msr_event_start
,
297 .stop
= msr_event_stop
,
298 .read
= msr_event_update
,
299 .capabilities
= PERF_PMU_CAP_NO_INTERRUPT
| PERF_PMU_CAP_NO_EXCLUDE
,
300 .attr_update
= attr_update
,
303 static int __init
msr_init(void)
305 if (!boot_cpu_has(X86_FEATURE_TSC
)) {
306 pr_cont("no MSR PMU driver.\n");
310 msr_mask
= perf_msr_probe(msr
, PERF_MSR_EVENT_MAX
, true, NULL
);
312 perf_pmu_register(&pmu_msr
, "msr", -1);
316 device_initcall(msr_init
);