1
2
3
4
5
6
7
8
9#include <linux/perf_event.h>
10#include <linux/init.h>
11#include <linux/export.h>
12#include <linux/pci.h>
13#include <linux/ptrace.h>
14#include <linux/syscore_ops.h>
15
16#include <asm/apic.h>
17
18#include "../perf_event.h"
19
20static u32 ibs_caps;
21
22#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD)
23
24#include <linux/kprobes.h>
25#include <linux/hardirq.h>
26
27#include <asm/nmi.h>
28
29#define IBS_FETCH_CONFIG_MASK (IBS_FETCH_RAND_EN | IBS_FETCH_MAX_CNT)
30#define IBS_OP_CONFIG_MASK IBS_OP_MAX_CNT
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67enum ibs_states {
68 IBS_ENABLED = 0,
69 IBS_STARTED = 1,
70 IBS_STOPPING = 2,
71 IBS_STOPPED = 3,
72
73 IBS_MAX_STATES,
74};
75
76struct cpu_perf_ibs {
77 struct perf_event *event;
78 unsigned long state[BITS_TO_LONGS(IBS_MAX_STATES)];
79};
80
81struct perf_ibs {
82 struct pmu pmu;
83 unsigned int msr;
84 u64 config_mask;
85 u64 cnt_mask;
86 u64 enable_mask;
87 u64 valid_mask;
88 u64 max_period;
89 unsigned long offset_mask[1];
90 int offset_max;
91 struct cpu_perf_ibs __percpu *pcpu;
92
93 struct attribute **format_attrs;
94 struct attribute_group format_group;
95 const struct attribute_group *attr_groups[2];
96
97 u64 (*get_count)(u64 config);
98};
99
100struct perf_ibs_data {
101 u32 size;
102 union {
103 u32 data[0];
104 u32 caps;
105 };
106 u64 regs[MSR_AMD64_IBS_REG_COUNT_MAX];
107};
108
109static int
110perf_event_set_period(struct hw_perf_event *hwc, u64 min, u64 max, u64 *hw_period)
111{
112 s64 left = local64_read(&hwc->period_left);
113 s64 period = hwc->sample_period;
114 int overflow = 0;
115
116
117
118
119 if (unlikely(left <= -period)) {
120 left = period;
121 local64_set(&hwc->period_left, left);
122 hwc->last_period = period;
123 overflow = 1;
124 }
125
126 if (unlikely(left < (s64)min)) {
127 left += period;
128 local64_set(&hwc->period_left, left);
129 hwc->last_period = period;
130 overflow = 1;
131 }
132
133
134
135
136
137
138
139 if (left > max) {
140 left -= max;
141 if (left > max)
142 left = max;
143 else if (left < min)
144 left = min;
145 }
146
147 *hw_period = (u64)left;
148
149 return overflow;
150}
151
152static int
153perf_event_try_update(struct perf_event *event, u64 new_raw_count, int width)
154{
155 struct hw_perf_event *hwc = &event->hw;
156 int shift = 64 - width;
157 u64 prev_raw_count;
158 u64 delta;
159
160
161
162
163
164
165
166
167 prev_raw_count = local64_read(&hwc->prev_count);
168 if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
169 new_raw_count) != prev_raw_count)
170 return 0;
171
172
173
174
175
176
177
178
179
180 delta = (new_raw_count << shift) - (prev_raw_count << shift);
181 delta >>= shift;
182
183 local64_add(delta, &event->count);
184 local64_sub(delta, &hwc->period_left);
185
186 return 1;
187}
188
189static struct perf_ibs perf_ibs_fetch;
190static struct perf_ibs perf_ibs_op;
191
192static struct perf_ibs *get_ibs_pmu(int type)
193{
194 if (perf_ibs_fetch.pmu.type == type)
195 return &perf_ibs_fetch;
196 if (perf_ibs_op.pmu.type == type)
197 return &perf_ibs_op;
198 return NULL;
199}
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218static int perf_ibs_precise_event(struct perf_event *event, u64 *config)
219{
220 switch (event->attr.precise_ip) {
221 case 0:
222 return -ENOENT;
223 case 1:
224 case 2:
225 break;
226 default:
227 return -EOPNOTSUPP;
228 }
229
230 switch (event->attr.type) {
231 case PERF_TYPE_HARDWARE:
232 switch (event->attr.config) {
233 case PERF_COUNT_HW_CPU_CYCLES:
234 *config = 0;
235 return 0;
236 }
237 break;
238 case PERF_TYPE_RAW:
239 switch (event->attr.config) {
240 case 0x0076:
241 *config = 0;
242 return 0;
243 case 0x00C1:
244 *config = IBS_OP_CNT_CTL;
245 return 0;
246 }
247 break;
248 default:
249 return -ENOENT;
250 }
251
252 return -EOPNOTSUPP;
253}
254
255static const struct perf_event_attr ibs_notsupp = {
256 .exclude_user = 1,
257 .exclude_kernel = 1,
258 .exclude_hv = 1,
259 .exclude_idle = 1,
260 .exclude_host = 1,
261 .exclude_guest = 1,
262};
263
264static int perf_ibs_init(struct perf_event *event)
265{
266 struct hw_perf_event *hwc = &event->hw;
267 struct perf_ibs *perf_ibs;
268 u64 max_cnt, config;
269 int ret;
270
271 perf_ibs = get_ibs_pmu(event->attr.type);
272 if (perf_ibs) {
273 config = event->attr.config;
274 } else {
275 perf_ibs = &perf_ibs_op;
276 ret = perf_ibs_precise_event(event, &config);
277 if (ret)
278 return ret;
279 }
280
281 if (event->pmu != &perf_ibs->pmu)
282 return -ENOENT;
283
284 if (perf_flags(&event->attr) & perf_flags(&ibs_notsupp))
285 return -EINVAL;
286
287 if (config & ~perf_ibs->config_mask)
288 return -EINVAL;
289
290 if (hwc->sample_period) {
291 if (config & perf_ibs->cnt_mask)
292
293 return -EINVAL;
294 if (!event->attr.sample_freq && hwc->sample_period & 0x0f)
295
296
297
298
299
300 return -EINVAL;
301 hwc->sample_period &= ~0x0FULL;
302 if (!hwc->sample_period)
303 hwc->sample_period = 0x10;
304 } else {
305 max_cnt = config & perf_ibs->cnt_mask;
306 config &= ~perf_ibs->cnt_mask;
307 event->attr.sample_period = max_cnt << 4;
308 hwc->sample_period = event->attr.sample_period;
309 }
310
311 if (!hwc->sample_period)
312 return -EINVAL;
313
314
315
316
317
318 hwc->last_period = hwc->sample_period;
319 local64_set(&hwc->period_left, hwc->sample_period);
320
321 hwc->config_base = perf_ibs->msr;
322 hwc->config = config;
323
324 return 0;
325}
326
327static int perf_ibs_set_period(struct perf_ibs *perf_ibs,
328 struct hw_perf_event *hwc, u64 *period)
329{
330 int overflow;
331
332
333 overflow = perf_event_set_period(hwc, 1<<4, perf_ibs->max_period, period);
334 local64_set(&hwc->prev_count, 0);
335
336 return overflow;
337}
338
339static u64 get_ibs_fetch_count(u64 config)
340{
341 return (config & IBS_FETCH_CNT) >> 12;
342}
343
344static u64 get_ibs_op_count(u64 config)
345{
346 u64 count = 0;
347
348 if (config & IBS_OP_VAL)
349 count += (config & IBS_OP_MAX_CNT) << 4;
350
351 if (ibs_caps & IBS_CAPS_RDWROPCNT)
352 count += (config & IBS_OP_CUR_CNT) >> 32;
353
354 return count;
355}
356
357static void
358perf_ibs_event_update(struct perf_ibs *perf_ibs, struct perf_event *event,
359 u64 *config)
360{
361 u64 count = perf_ibs->get_count(*config);
362
363
364
365
366
367
368 while (!perf_event_try_update(event, count, 64)) {
369 rdmsrl(event->hw.config_base, *config);
370 count = perf_ibs->get_count(*config);
371 }
372}
373
374static inline void perf_ibs_enable_event(struct perf_ibs *perf_ibs,
375 struct hw_perf_event *hwc, u64 config)
376{
377 wrmsrl(hwc->config_base, hwc->config | config | perf_ibs->enable_mask);
378}
379
380
381
382
383
384
385
386
387static inline void perf_ibs_disable_event(struct perf_ibs *perf_ibs,
388 struct hw_perf_event *hwc, u64 config)
389{
390 config &= ~perf_ibs->cnt_mask;
391 wrmsrl(hwc->config_base, config);
392 config &= ~perf_ibs->enable_mask;
393 wrmsrl(hwc->config_base, config);
394}
395
396
397
398
399
400
401
402static void perf_ibs_start(struct perf_event *event, int flags)
403{
404 struct hw_perf_event *hwc = &event->hw;
405 struct perf_ibs *perf_ibs = container_of(event->pmu, struct perf_ibs, pmu);
406 struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
407 u64 period;
408
409 if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
410 return;
411
412 WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
413 hwc->state = 0;
414
415 perf_ibs_set_period(perf_ibs, hwc, &period);
416
417
418
419
420 set_bit(IBS_STARTED, pcpu->state);
421 clear_bit(IBS_STOPPING, pcpu->state);
422 perf_ibs_enable_event(perf_ibs, hwc, period >> 4);
423
424 perf_event_update_userpage(event);
425}
426
427static void perf_ibs_stop(struct perf_event *event, int flags)
428{
429 struct hw_perf_event *hwc = &event->hw;
430 struct perf_ibs *perf_ibs = container_of(event->pmu, struct perf_ibs, pmu);
431 struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
432 u64 config;
433 int stopping;
434
435 if (test_and_set_bit(IBS_STOPPING, pcpu->state))
436 return;
437
438 stopping = test_bit(IBS_STARTED, pcpu->state);
439
440 if (!stopping && (hwc->state & PERF_HES_UPTODATE))
441 return;
442
443 rdmsrl(hwc->config_base, config);
444
445 if (stopping) {
446
447
448
449
450
451
452 set_bit(IBS_STOPPED, pcpu->state);
453 perf_ibs_disable_event(perf_ibs, hwc, config);
454
455
456
457
458
459
460
461
462
463 clear_bit(IBS_STARTED, pcpu->state);
464 WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
465 hwc->state |= PERF_HES_STOPPED;
466 }
467
468 if (hwc->state & PERF_HES_UPTODATE)
469 return;
470
471
472
473
474
475 config &= ~perf_ibs->valid_mask;
476
477 perf_ibs_event_update(perf_ibs, event, &config);
478 hwc->state |= PERF_HES_UPTODATE;
479}
480
481static int perf_ibs_add(struct perf_event *event, int flags)
482{
483 struct perf_ibs *perf_ibs = container_of(event->pmu, struct perf_ibs, pmu);
484 struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
485
486 if (test_and_set_bit(IBS_ENABLED, pcpu->state))
487 return -ENOSPC;
488
489 event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
490
491 pcpu->event = event;
492
493 if (flags & PERF_EF_START)
494 perf_ibs_start(event, PERF_EF_RELOAD);
495
496 return 0;
497}
498
499static void perf_ibs_del(struct perf_event *event, int flags)
500{
501 struct perf_ibs *perf_ibs = container_of(event->pmu, struct perf_ibs, pmu);
502 struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
503
504 if (!test_and_clear_bit(IBS_ENABLED, pcpu->state))
505 return;
506
507 perf_ibs_stop(event, PERF_EF_UPDATE);
508
509 pcpu->event = NULL;
510
511 perf_event_update_userpage(event);
512}
513
514static void perf_ibs_read(struct perf_event *event) { }
515
516PMU_FORMAT_ATTR(rand_en, "config:57");
517PMU_FORMAT_ATTR(cnt_ctl, "config:19");
518
519static struct attribute *ibs_fetch_format_attrs[] = {
520 &format_attr_rand_en.attr,
521 NULL,
522};
523
524static struct attribute *ibs_op_format_attrs[] = {
525 NULL,
526 NULL,
527};
528
529static struct perf_ibs perf_ibs_fetch = {
530 .pmu = {
531 .task_ctx_nr = perf_invalid_context,
532
533 .event_init = perf_ibs_init,
534 .add = perf_ibs_add,
535 .del = perf_ibs_del,
536 .start = perf_ibs_start,
537 .stop = perf_ibs_stop,
538 .read = perf_ibs_read,
539 },
540 .msr = MSR_AMD64_IBSFETCHCTL,
541 .config_mask = IBS_FETCH_CONFIG_MASK,
542 .cnt_mask = IBS_FETCH_MAX_CNT,
543 .enable_mask = IBS_FETCH_ENABLE,
544 .valid_mask = IBS_FETCH_VAL,
545 .max_period = IBS_FETCH_MAX_CNT << 4,
546 .offset_mask = { MSR_AMD64_IBSFETCH_REG_MASK },
547 .offset_max = MSR_AMD64_IBSFETCH_REG_COUNT,
548 .format_attrs = ibs_fetch_format_attrs,
549
550 .get_count = get_ibs_fetch_count,
551};
552
553static struct perf_ibs perf_ibs_op = {
554 .pmu = {
555 .task_ctx_nr = perf_invalid_context,
556
557 .event_init = perf_ibs_init,
558 .add = perf_ibs_add,
559 .del = perf_ibs_del,
560 .start = perf_ibs_start,
561 .stop = perf_ibs_stop,
562 .read = perf_ibs_read,
563 },
564 .msr = MSR_AMD64_IBSOPCTL,
565 .config_mask = IBS_OP_CONFIG_MASK,
566 .cnt_mask = IBS_OP_MAX_CNT,
567 .enable_mask = IBS_OP_ENABLE,
568 .valid_mask = IBS_OP_VAL,
569 .max_period = IBS_OP_MAX_CNT << 4,
570 .offset_mask = { MSR_AMD64_IBSOP_REG_MASK },
571 .offset_max = MSR_AMD64_IBSOP_REG_COUNT,
572 .format_attrs = ibs_op_format_attrs,
573
574 .get_count = get_ibs_op_count,
575};
576
577static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
578{
579 struct cpu_perf_ibs *pcpu = this_cpu_ptr(perf_ibs->pcpu);
580 struct perf_event *event = pcpu->event;
581 struct hw_perf_event *hwc = &event->hw;
582 struct perf_sample_data data;
583 struct perf_raw_record raw;
584 struct pt_regs regs;
585 struct perf_ibs_data ibs_data;
586 int offset, size, check_rip, offset_max, throttle = 0;
587 unsigned int msr;
588 u64 *buf, *config, period;
589
590 if (!test_bit(IBS_STARTED, pcpu->state)) {
591fail:
592
593
594
595
596
597
598 if (test_and_clear_bit(IBS_STOPPED, pcpu->state))
599 return 1;
600
601 return 0;
602 }
603
604 msr = hwc->config_base;
605 buf = ibs_data.regs;
606 rdmsrl(msr, *buf);
607 if (!(*buf++ & perf_ibs->valid_mask))
608 goto fail;
609
610 config = &ibs_data.regs[0];
611 perf_ibs_event_update(perf_ibs, event, config);
612 perf_sample_data_init(&data, 0, hwc->last_period);
613 if (!perf_ibs_set_period(perf_ibs, hwc, &period))
614 goto out;
615
616 ibs_data.caps = ibs_caps;
617 size = 1;
618 offset = 1;
619 check_rip = (perf_ibs == &perf_ibs_op && (ibs_caps & IBS_CAPS_RIPINVALIDCHK));
620 if (event->attr.sample_type & PERF_SAMPLE_RAW)
621 offset_max = perf_ibs->offset_max;
622 else if (check_rip)
623 offset_max = 2;
624 else
625 offset_max = 1;
626 do {
627 rdmsrl(msr + offset, *buf++);
628 size++;
629 offset = find_next_bit(perf_ibs->offset_mask,
630 perf_ibs->offset_max,
631 offset + 1);
632 } while (offset < offset_max);
633 if (event->attr.sample_type & PERF_SAMPLE_RAW) {
634
635
636
637
638
639 if (ibs_caps & IBS_CAPS_BRNTRGT) {
640 rdmsrl(MSR_AMD64_IBSBRTARGET, *buf++);
641 size++;
642 }
643 if (ibs_caps & IBS_CAPS_OPDATA4) {
644 rdmsrl(MSR_AMD64_IBSOPDATA4, *buf++);
645 size++;
646 }
647 }
648 ibs_data.size = sizeof(u64) * size;
649
650 regs = *iregs;
651 if (check_rip && (ibs_data.regs[2] & IBS_RIP_INVALID)) {
652 regs.flags &= ~PERF_EFLAGS_EXACT;
653 } else {
654 set_linear_ip(®s, ibs_data.regs[1]);
655 regs.flags |= PERF_EFLAGS_EXACT;
656 }
657
658 if (event->attr.sample_type & PERF_SAMPLE_RAW) {
659 raw = (struct perf_raw_record){
660 .frag = {
661 .size = sizeof(u32) + ibs_data.size,
662 .data = ibs_data.data,
663 },
664 };
665 data.raw = &raw;
666 }
667
668 throttle = perf_event_overflow(event, &data, ®s);
669out:
670 if (throttle)
671 perf_ibs_stop(event, 0);
672 else
673 perf_ibs_enable_event(perf_ibs, hwc, period >> 4);
674
675 perf_event_update_userpage(event);
676
677 return 1;
678}
679
680static int
681perf_ibs_nmi_handler(unsigned int cmd, struct pt_regs *regs)
682{
683 u64 stamp = sched_clock();
684 int handled = 0;
685
686 handled += perf_ibs_handle_irq(&perf_ibs_fetch, regs);
687 handled += perf_ibs_handle_irq(&perf_ibs_op, regs);
688
689 if (handled)
690 inc_irq_stat(apic_perf_irqs);
691
692 perf_sample_event_took(sched_clock() - stamp);
693
694 return handled;
695}
696NOKPROBE_SYMBOL(perf_ibs_nmi_handler);
697
698static __init int perf_ibs_pmu_init(struct perf_ibs *perf_ibs, char *name)
699{
700 struct cpu_perf_ibs __percpu *pcpu;
701 int ret;
702
703 pcpu = alloc_percpu(struct cpu_perf_ibs);
704 if (!pcpu)
705 return -ENOMEM;
706
707 perf_ibs->pcpu = pcpu;
708
709
710 if (perf_ibs->format_attrs[0]) {
711 memset(&perf_ibs->format_group, 0, sizeof(perf_ibs->format_group));
712 perf_ibs->format_group.name = "format";
713 perf_ibs->format_group.attrs = perf_ibs->format_attrs;
714
715 memset(&perf_ibs->attr_groups, 0, sizeof(perf_ibs->attr_groups));
716 perf_ibs->attr_groups[0] = &perf_ibs->format_group;
717 perf_ibs->pmu.attr_groups = perf_ibs->attr_groups;
718 }
719
720 ret = perf_pmu_register(&perf_ibs->pmu, name, -1);
721 if (ret) {
722 perf_ibs->pcpu = NULL;
723 free_percpu(pcpu);
724 }
725
726 return ret;
727}
728
729static __init void perf_event_ibs_init(void)
730{
731 struct attribute **attr = ibs_op_format_attrs;
732
733 perf_ibs_pmu_init(&perf_ibs_fetch, "ibs_fetch");
734
735 if (ibs_caps & IBS_CAPS_OPCNT) {
736 perf_ibs_op.config_mask |= IBS_OP_CNT_CTL;
737 *attr++ = &format_attr_cnt_ctl.attr;
738 }
739 perf_ibs_pmu_init(&perf_ibs_op, "ibs_op");
740
741 register_nmi_handler(NMI_LOCAL, perf_ibs_nmi_handler, 0, "perf_ibs");
742 pr_info("perf: AMD IBS detected (0x%08x)\n", ibs_caps);
743}
744
745#else
746
747static __init void perf_event_ibs_init(void) { }
748
749#endif
750
751
752
753static __init u32 __get_ibs_caps(void)
754{
755 u32 caps;
756 unsigned int max_level;
757
758 if (!boot_cpu_has(X86_FEATURE_IBS))
759 return 0;
760
761
762 max_level = cpuid_eax(0x80000000);
763 if (max_level < IBS_CPUID_FEATURES)
764 return IBS_CAPS_DEFAULT;
765
766 caps = cpuid_eax(IBS_CPUID_FEATURES);
767 if (!(caps & IBS_CAPS_AVAIL))
768
769 return IBS_CAPS_DEFAULT;
770
771 return caps;
772}
773
774u32 get_ibs_caps(void)
775{
776 return ibs_caps;
777}
778
779EXPORT_SYMBOL(get_ibs_caps);
780
781static inline int get_eilvt(int offset)
782{
783 return !setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 1);
784}
785
786static inline int put_eilvt(int offset)
787{
788 return !setup_APIC_eilvt(offset, 0, 0, 1);
789}
790
791
792
793
794static inline int ibs_eilvt_valid(void)
795{
796 int offset;
797 u64 val;
798 int valid = 0;
799
800 preempt_disable();
801
802 rdmsrl(MSR_AMD64_IBSCTL, val);
803 offset = val & IBSCTL_LVT_OFFSET_MASK;
804
805 if (!(val & IBSCTL_LVT_OFFSET_VALID)) {
806 pr_err(FW_BUG "cpu %d, invalid IBS interrupt offset %d (MSR%08X=0x%016llx)\n",
807 smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
808 goto out;
809 }
810
811 if (!get_eilvt(offset)) {
812 pr_err(FW_BUG "cpu %d, IBS interrupt offset %d not available (MSR%08X=0x%016llx)\n",
813 smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
814 goto out;
815 }
816
817 valid = 1;
818out:
819 preempt_enable();
820
821 return valid;
822}
823
824static int setup_ibs_ctl(int ibs_eilvt_off)
825{
826 struct pci_dev *cpu_cfg;
827 int nodes;
828 u32 value = 0;
829
830 nodes = 0;
831 cpu_cfg = NULL;
832 do {
833 cpu_cfg = pci_get_device(PCI_VENDOR_ID_AMD,
834 PCI_DEVICE_ID_AMD_10H_NB_MISC,
835 cpu_cfg);
836 if (!cpu_cfg)
837 break;
838 ++nodes;
839 pci_write_config_dword(cpu_cfg, IBSCTL, ibs_eilvt_off
840 | IBSCTL_LVT_OFFSET_VALID);
841 pci_read_config_dword(cpu_cfg, IBSCTL, &value);
842 if (value != (ibs_eilvt_off | IBSCTL_LVT_OFFSET_VALID)) {
843 pci_dev_put(cpu_cfg);
844 pr_debug("Failed to setup IBS LVT offset, IBSCTL = 0x%08x\n",
845 value);
846 return -EINVAL;
847 }
848 } while (1);
849
850 if (!nodes) {
851 pr_debug("No CPU node configured for IBS\n");
852 return -ENODEV;
853 }
854
855 return 0;
856}
857
858
859
860
861
862
863
864
865
866static void force_ibs_eilvt_setup(void)
867{
868 int offset;
869 int ret;
870
871 preempt_disable();
872
873 for (offset = 1; offset < APIC_EILVT_NR_MAX; offset++) {
874 if (get_eilvt(offset))
875 break;
876 }
877 preempt_enable();
878
879 if (offset == APIC_EILVT_NR_MAX) {
880 pr_debug("No EILVT entry available\n");
881 return;
882 }
883
884 ret = setup_ibs_ctl(offset);
885 if (ret)
886 goto out;
887
888 if (!ibs_eilvt_valid())
889 goto out;
890
891 pr_info("IBS: LVT offset %d assigned\n", offset);
892
893 return;
894out:
895 preempt_disable();
896 put_eilvt(offset);
897 preempt_enable();
898 return;
899}
900
901static void ibs_eilvt_setup(void)
902{
903
904
905
906
907
908
909 if (boot_cpu_data.x86 == 0x10)
910 force_ibs_eilvt_setup();
911}
912
913static inline int get_ibs_lvt_offset(void)
914{
915 u64 val;
916
917 rdmsrl(MSR_AMD64_IBSCTL, val);
918 if (!(val & IBSCTL_LVT_OFFSET_VALID))
919 return -EINVAL;
920
921 return val & IBSCTL_LVT_OFFSET_MASK;
922}
923
924static void setup_APIC_ibs(void)
925{
926 int offset;
927
928 offset = get_ibs_lvt_offset();
929 if (offset < 0)
930 goto failed;
931
932 if (!setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 0))
933 return;
934failed:
935 pr_warn("perf: IBS APIC setup failed on cpu #%d\n",
936 smp_processor_id());
937}
938
939static void clear_APIC_ibs(void)
940{
941 int offset;
942
943 offset = get_ibs_lvt_offset();
944 if (offset >= 0)
945 setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_FIX, 1);
946}
947
948static int x86_pmu_amd_ibs_starting_cpu(unsigned int cpu)
949{
950 setup_APIC_ibs();
951 return 0;
952}
953
954#ifdef CONFIG_PM
955
956static int perf_ibs_suspend(void)
957{
958 clear_APIC_ibs();
959 return 0;
960}
961
962static void perf_ibs_resume(void)
963{
964 ibs_eilvt_setup();
965 setup_APIC_ibs();
966}
967
968static struct syscore_ops perf_ibs_syscore_ops = {
969 .resume = perf_ibs_resume,
970 .suspend = perf_ibs_suspend,
971};
972
973static void perf_ibs_pm_init(void)
974{
975 register_syscore_ops(&perf_ibs_syscore_ops);
976}
977
978#else
979
980static inline void perf_ibs_pm_init(void) { }
981
982#endif
983
984static int x86_pmu_amd_ibs_dying_cpu(unsigned int cpu)
985{
986 clear_APIC_ibs();
987 return 0;
988}
989
990static __init int amd_ibs_init(void)
991{
992 u32 caps;
993
994 caps = __get_ibs_caps();
995 if (!caps)
996 return -ENODEV;
997
998 ibs_eilvt_setup();
999
1000 if (!ibs_eilvt_valid())
1001 return -EINVAL;
1002
1003 perf_ibs_pm_init();
1004
1005 ibs_caps = caps;
1006
1007 smp_mb();
1008
1009
1010
1011
1012 cpuhp_setup_state(CPUHP_AP_PERF_X86_AMD_IBS_STARTING,
1013 "perf/x86/amd/ibs:starting",
1014 x86_pmu_amd_ibs_starting_cpu,
1015 x86_pmu_amd_ibs_dying_cpu);
1016
1017 perf_event_ibs_init();
1018
1019 return 0;
1020}
1021
1022
1023device_initcall(amd_ibs_init);
1024