aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/Makefile.config6
-rw-r--r--tools/perf/arch/s390/include/dwarf-regs-table.h71
-rw-r--r--tools/perf/arch/s390/include/perf_regs.h95
-rw-r--r--tools/perf/arch/s390/util/Build3
-rw-r--r--tools/perf/arch/s390/util/auxtrace.c118
-rw-r--r--tools/perf/arch/s390/util/dwarf-regs.c11
-rw-r--r--tools/perf/arch/s390/util/unwind-libdw.c63
-rw-r--r--tools/perf/builtin-kmem.c2
8 files changed, 354 insertions, 15 deletions
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 63f534a0902f..ed65e82f034e 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -53,6 +53,10 @@ ifeq ($(SRCARCH),arm64)
53 LIBUNWIND_LIBS = -lunwind -lunwind-aarch64 53 LIBUNWIND_LIBS = -lunwind -lunwind-aarch64
54endif 54endif
55 55
56ifeq ($(ARCH),s390)
57 NO_PERF_REGS := 0
58endif
59
56ifeq ($(NO_PERF_REGS),0) 60ifeq ($(NO_PERF_REGS),0)
57 $(call detected,CONFIG_PERF_REGS) 61 $(call detected,CONFIG_PERF_REGS)
58endif 62endif
@@ -61,7 +65,7 @@ endif
61# Disable it on all other architectures in case libdw unwind 65# Disable it on all other architectures in case libdw unwind
62# support is detected in system. Add supported architectures 66# support is detected in system. Add supported architectures
63# to the check. 67# to the check.
64ifneq ($(SRCARCH),$(filter $(SRCARCH),x86 arm powerpc)) 68ifneq ($(SRCARCH),$(filter $(SRCARCH),x86 arm powerpc s390))
65 NO_LIBDW_DWARF_UNWIND := 1 69 NO_LIBDW_DWARF_UNWIND := 1
66endif 70endif
67 71
diff --git a/tools/perf/arch/s390/include/dwarf-regs-table.h b/tools/perf/arch/s390/include/dwarf-regs-table.h
index 792d4c277225..671553525f41 100644
--- a/tools/perf/arch/s390/include/dwarf-regs-table.h
+++ b/tools/perf/arch/s390/include/dwarf-regs-table.h
@@ -1,9 +1,72 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2#ifdef DEFINE_DWARF_REGSTR_TABLE 2#ifndef S390_DWARF_REGS_TABLE_H
3/* This is included in perf/util/dwarf-regs.c */ 3#define S390_DWARF_REGS_TABLE_H
4 4
5static const char * const s390_regstr_tbl[] = { 5#define REG_DWARFNUM_NAME(reg, idx) [idx] = "%" #reg
6
7/*
8 * For reference, see DWARF register mapping:
9 * http://refspecs.linuxfoundation.org/ELF/zSeries/lzsabi0_s390/x1542.html
10 */
11static const char * const s390_dwarf_regs[] = {
6 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", 12 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
7 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", 13 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
14 REG_DWARFNUM_NAME(f0, 16),
15 REG_DWARFNUM_NAME(f1, 20),
16 REG_DWARFNUM_NAME(f2, 17),
17 REG_DWARFNUM_NAME(f3, 21),
18 REG_DWARFNUM_NAME(f4, 18),
19 REG_DWARFNUM_NAME(f5, 22),
20 REG_DWARFNUM_NAME(f6, 19),
21 REG_DWARFNUM_NAME(f7, 23),
22 REG_DWARFNUM_NAME(f8, 24),
23 REG_DWARFNUM_NAME(f9, 28),
24 REG_DWARFNUM_NAME(f10, 25),
25 REG_DWARFNUM_NAME(f11, 29),
26 REG_DWARFNUM_NAME(f12, 26),
27 REG_DWARFNUM_NAME(f13, 30),
28 REG_DWARFNUM_NAME(f14, 27),
29 REG_DWARFNUM_NAME(f15, 31),
30 REG_DWARFNUM_NAME(c0, 32),
31 REG_DWARFNUM_NAME(c1, 33),
32 REG_DWARFNUM_NAME(c2, 34),
33 REG_DWARFNUM_NAME(c3, 35),
34 REG_DWARFNUM_NAME(c4, 36),
35 REG_DWARFNUM_NAME(c5, 37),
36 REG_DWARFNUM_NAME(c6, 38),
37 REG_DWARFNUM_NAME(c7, 39),
38 REG_DWARFNUM_NAME(c8, 40),
39 REG_DWARFNUM_NAME(c9, 41),
40 REG_DWARFNUM_NAME(c10, 42),
41 REG_DWARFNUM_NAME(c11, 43),
42 REG_DWARFNUM_NAME(c12, 44),
43 REG_DWARFNUM_NAME(c13, 45),
44 REG_DWARFNUM_NAME(c14, 46),
45 REG_DWARFNUM_NAME(c15, 47),
46 REG_DWARFNUM_NAME(a0, 48),
47 REG_DWARFNUM_NAME(a1, 49),
48 REG_DWARFNUM_NAME(a2, 50),
49 REG_DWARFNUM_NAME(a3, 51),
50 REG_DWARFNUM_NAME(a4, 52),
51 REG_DWARFNUM_NAME(a5, 53),
52 REG_DWARFNUM_NAME(a6, 54),
53 REG_DWARFNUM_NAME(a7, 55),
54 REG_DWARFNUM_NAME(a8, 56),
55 REG_DWARFNUM_NAME(a9, 57),
56 REG_DWARFNUM_NAME(a10, 58),
57 REG_DWARFNUM_NAME(a11, 59),
58 REG_DWARFNUM_NAME(a12, 60),
59 REG_DWARFNUM_NAME(a13, 61),
60 REG_DWARFNUM_NAME(a14, 62),
61 REG_DWARFNUM_NAME(a15, 63),
62 REG_DWARFNUM_NAME(pswm, 64),
63 REG_DWARFNUM_NAME(pswa, 65),
8}; 64};
9#endif 65
66#ifdef DEFINE_DWARF_REGSTR_TABLE
67/* This is included in perf/util/dwarf-regs.c */
68
69#define s390_regstr_tbl s390_dwarf_regs
70
71#endif /* DEFINE_DWARF_REGSTR_TABLE */
72#endif /* S390_DWARF_REGS_TABLE_H */
diff --git a/tools/perf/arch/s390/include/perf_regs.h b/tools/perf/arch/s390/include/perf_regs.h
new file mode 100644
index 000000000000..d2df54a6bc5a
--- /dev/null
+++ b/tools/perf/arch/s390/include/perf_regs.h
@@ -0,0 +1,95 @@
1#ifndef ARCH_PERF_REGS_H
2#define ARCH_PERF_REGS_H
3
4#include <stdlib.h>
5#include <linux/types.h>
6#include <../../../../arch/s390/include/uapi/asm/perf_regs.h>
7
8void perf_regs_load(u64 *regs);
9
10#define PERF_REGS_MASK ((1ULL << PERF_REG_S390_MAX) - 1)
11#define PERF_REGS_MAX PERF_REG_S390_MAX
12#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_64
13
14#define PERF_REG_IP PERF_REG_S390_PC
15#define PERF_REG_SP PERF_REG_S390_R15
16
17static inline const char *perf_reg_name(int id)
18{
19 switch (id) {
20 case PERF_REG_S390_R0:
21 return "R0";
22 case PERF_REG_S390_R1:
23 return "R1";
24 case PERF_REG_S390_R2:
25 return "R2";
26 case PERF_REG_S390_R3:
27 return "R3";
28 case PERF_REG_S390_R4:
29 return "R4";
30 case PERF_REG_S390_R5:
31 return "R5";
32 case PERF_REG_S390_R6:
33 return "R6";
34 case PERF_REG_S390_R7:
35 return "R7";
36 case PERF_REG_S390_R8:
37 return "R8";
38 case PERF_REG_S390_R9:
39 return "R9";
40 case PERF_REG_S390_R10:
41 return "R10";
42 case PERF_REG_S390_R11:
43 return "R11";
44 case PERF_REG_S390_R12:
45 return "R12";
46 case PERF_REG_S390_R13:
47 return "R13";
48 case PERF_REG_S390_R14:
49 return "R14";
50 case PERF_REG_S390_R15:
51 return "R15";
52 case PERF_REG_S390_FP0:
53 return "FP0";
54 case PERF_REG_S390_FP1:
55 return "FP1";
56 case PERF_REG_S390_FP2:
57 return "FP2";
58 case PERF_REG_S390_FP3:
59 return "FP3";
60 case PERF_REG_S390_FP4:
61 return "FP4";
62 case PERF_REG_S390_FP5:
63 return "FP5";
64 case PERF_REG_S390_FP6:
65 return "FP6";
66 case PERF_REG_S390_FP7:
67 return "FP7";
68 case PERF_REG_S390_FP8:
69 return "FP8";
70 case PERF_REG_S390_FP9:
71 return "FP9";
72 case PERF_REG_S390_FP10:
73 return "FP10";
74 case PERF_REG_S390_FP11:
75 return "FP11";
76 case PERF_REG_S390_FP12:
77 return "FP12";
78 case PERF_REG_S390_FP13:
79 return "FP13";
80 case PERF_REG_S390_FP14:
81 return "FP14";
82 case PERF_REG_S390_FP15:
83 return "FP15";
84 case PERF_REG_S390_MASK:
85 return "MASK";
86 case PERF_REG_S390_PC:
87 return "PC";
88 default:
89 return NULL;
90 }
91
92 return NULL;
93}
94
95#endif /* ARCH_PERF_REGS_H */
diff --git a/tools/perf/arch/s390/util/Build b/tools/perf/arch/s390/util/Build
index 5bd7b9260cc0..4a233683c684 100644
--- a/tools/perf/arch/s390/util/Build
+++ b/tools/perf/arch/s390/util/Build
@@ -2,5 +2,8 @@ libperf-y += header.o
2libperf-y += kvm-stat.o 2libperf-y += kvm-stat.o
3 3
4libperf-$(CONFIG_DWARF) += dwarf-regs.o 4libperf-$(CONFIG_DWARF) += dwarf-regs.o
5libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
5 6
6libperf-y += machine.o 7libperf-y += machine.o
8
9libperf-$(CONFIG_AUXTRACE) += auxtrace.o
diff --git a/tools/perf/arch/s390/util/auxtrace.c b/tools/perf/arch/s390/util/auxtrace.c
new file mode 100644
index 000000000000..6cb48e4cffd9
--- /dev/null
+++ b/tools/perf/arch/s390/util/auxtrace.c
@@ -0,0 +1,118 @@
1#include <stdbool.h>
2#include <linux/kernel.h>
3#include <linux/types.h>
4#include <linux/bitops.h>
5#include <linux/log2.h>
6
7#include "../../util/evlist.h"
8#include "../../util/auxtrace.h"
9#include "../../util/evsel.h"
10
11#define PERF_EVENT_CPUM_SF 0xB0000 /* Event: Basic-sampling */
12#define PERF_EVENT_CPUM_SF_DIAG 0xBD000 /* Event: Combined-sampling */
13#define DEFAULT_AUX_PAGES 128
14#define DEFAULT_FREQ 4000
15
16static void cpumsf_free(struct auxtrace_record *itr)
17{
18 free(itr);
19}
20
21static size_t cpumsf_info_priv_size(struct auxtrace_record *itr __maybe_unused,
22 struct perf_evlist *evlist __maybe_unused)
23{
24 return 0;
25}
26
27static int
28cpumsf_info_fill(struct auxtrace_record *itr __maybe_unused,
29 struct perf_session *session __maybe_unused,
30 struct auxtrace_info_event *auxtrace_info __maybe_unused,
31 size_t priv_size __maybe_unused)
32{
33 return 0;
34}
35
36static unsigned long
37cpumsf_reference(struct auxtrace_record *itr __maybe_unused)
38{
39 return 0;
40}
41
42static int
43cpumsf_recording_options(struct auxtrace_record *ar __maybe_unused,
44 struct perf_evlist *evlist __maybe_unused,
45 struct record_opts *opts)
46{
47 unsigned int factor = 1;
48 unsigned int pages;
49
50 opts->full_auxtrace = true;
51
52 /*
53 * The AUX buffer size should be set properly to avoid
54 * overflow of samples if it is not set explicitly.
55 * DEFAULT_AUX_PAGES is an proper size when sampling frequency
56 * is DEFAULT_FREQ. It is expected to hold about 1/2 second
57 * of sampling data. The size used for AUX buffer will scale
58 * according to the specified frequency and DEFAULT_FREQ.
59 */
60 if (!opts->auxtrace_mmap_pages) {
61 if (opts->user_freq != UINT_MAX)
62 factor = (opts->user_freq + DEFAULT_FREQ
63 - 1) / DEFAULT_FREQ;
64 pages = DEFAULT_AUX_PAGES * factor;
65 opts->auxtrace_mmap_pages = roundup_pow_of_two(pages);
66 }
67
68 return 0;
69}
70
71static int
72cpumsf_parse_snapshot_options(struct auxtrace_record *itr __maybe_unused,
73 struct record_opts *opts __maybe_unused,
74 const char *str __maybe_unused)
75{
76 return 0;
77}
78
79/*
80 * auxtrace_record__init is called when perf record
81 * check if the event really need auxtrace
82 */
83struct auxtrace_record *auxtrace_record__init(struct perf_evlist *evlist,
84 int *err)
85{
86 struct auxtrace_record *aux;
87 struct perf_evsel *pos;
88 int diagnose = 0;
89
90 if (evlist->nr_entries == 0)
91 return NULL;
92
93 evlist__for_each_entry(evlist, pos) {
94 if (pos->attr.config == PERF_EVENT_CPUM_SF_DIAG) {
95 diagnose = 1;
96 break;
97 }
98 }
99
100 if (!diagnose)
101 return NULL;
102
103 /* sampling in diagnose mode. alloc aux buffer */
104 aux = zalloc(sizeof(*aux));
105 if (aux == NULL) {
106 *err = -ENOMEM;
107 return NULL;
108 }
109
110 aux->parse_snapshot_options = cpumsf_parse_snapshot_options;
111 aux->recording_options = cpumsf_recording_options;
112 aux->info_priv_size = cpumsf_info_priv_size;
113 aux->info_fill = cpumsf_info_fill;
114 aux->free = cpumsf_free;
115 aux->reference = cpumsf_reference;
116
117 return aux;
118}
diff --git a/tools/perf/arch/s390/util/dwarf-regs.c b/tools/perf/arch/s390/util/dwarf-regs.c
index 0dff5b2ed1e5..f47576ce13ea 100644
--- a/tools/perf/arch/s390/util/dwarf-regs.c
+++ b/tools/perf/arch/s390/util/dwarf-regs.c
@@ -9,15 +9,10 @@
9 9
10#include <stddef.h> 10#include <stddef.h>
11#include <dwarf-regs.h> 11#include <dwarf-regs.h>
12 12#include <linux/kernel.h>
13#define NUM_GPRS 16 13#include "dwarf-regs-table.h"
14
15static const char *gpr_names[NUM_GPRS] = {
16 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
17 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
18};
19 14
20const char *get_arch_regstr(unsigned int n) 15const char *get_arch_regstr(unsigned int n)
21{ 16{
22 return (n >= NUM_GPRS) ? NULL : gpr_names[n]; 17 return (n >= ARRAY_SIZE(s390_dwarf_regs)) ? NULL : s390_dwarf_regs[n];
23} 18}
diff --git a/tools/perf/arch/s390/util/unwind-libdw.c b/tools/perf/arch/s390/util/unwind-libdw.c
new file mode 100644
index 000000000000..387c698cdd1b
--- /dev/null
+++ b/tools/perf/arch/s390/util/unwind-libdw.c
@@ -0,0 +1,63 @@
1#include <linux/kernel.h>
2#include <elfutils/libdwfl.h>
3#include "../../util/unwind-libdw.h"
4#include "../../util/perf_regs.h"
5#include "../../util/event.h"
6#include "dwarf-regs-table.h"
7
8
9bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg)
10{
11 struct unwind_info *ui = arg;
12 struct regs_dump *user_regs = &ui->sample->user_regs;
13 Dwarf_Word dwarf_regs[ARRAY_SIZE(s390_dwarf_regs)];
14
15#define REG(r) ({ \
16 Dwarf_Word val = 0; \
17 perf_reg_value(&val, user_regs, PERF_REG_S390_##r); \
18 val; \
19})
20 /*
21 * For DWARF register mapping details,
22 * see also perf/arch/s390/include/dwarf-regs-table.h
23 */
24 dwarf_regs[0] = REG(R0);
25 dwarf_regs[1] = REG(R1);
26 dwarf_regs[2] = REG(R2);
27 dwarf_regs[3] = REG(R3);
28 dwarf_regs[4] = REG(R4);
29 dwarf_regs[5] = REG(R5);
30 dwarf_regs[6] = REG(R6);
31 dwarf_regs[7] = REG(R7);
32 dwarf_regs[8] = REG(R8);
33 dwarf_regs[9] = REG(R9);
34 dwarf_regs[10] = REG(R10);
35 dwarf_regs[11] = REG(R11);
36 dwarf_regs[12] = REG(R12);
37 dwarf_regs[13] = REG(R13);
38 dwarf_regs[14] = REG(R14);
39 dwarf_regs[15] = REG(R15);
40
41 dwarf_regs[16] = REG(FP0);
42 dwarf_regs[17] = REG(FP2);
43 dwarf_regs[18] = REG(FP4);
44 dwarf_regs[19] = REG(FP6);
45 dwarf_regs[20] = REG(FP1);
46 dwarf_regs[21] = REG(FP3);
47 dwarf_regs[22] = REG(FP5);
48 dwarf_regs[23] = REG(FP7);
49 dwarf_regs[24] = REG(FP8);
50 dwarf_regs[25] = REG(FP10);
51 dwarf_regs[26] = REG(FP12);
52 dwarf_regs[27] = REG(FP14);
53 dwarf_regs[28] = REG(FP9);
54 dwarf_regs[29] = REG(FP11);
55 dwarf_regs[30] = REG(FP13);
56 dwarf_regs[31] = REG(FP15);
57
58 dwarf_regs[64] = REG(MASK);
59 dwarf_regs[65] = REG(PC);
60
61 dwfl_thread_state_register_pc(thread, dwarf_regs[65]);
62 return dwfl_thread_state_registers(thread, 0, 32, dwarf_regs);
63}
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 557d391f564a..ae11e4c3516a 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -641,7 +641,6 @@ static const struct {
641 { "__GFP_ATOMIC", "_A" }, 641 { "__GFP_ATOMIC", "_A" },
642 { "__GFP_IO", "I" }, 642 { "__GFP_IO", "I" },
643 { "__GFP_FS", "F" }, 643 { "__GFP_FS", "F" },
644 { "__GFP_COLD", "CO" },
645 { "__GFP_NOWARN", "NWR" }, 644 { "__GFP_NOWARN", "NWR" },
646 { "__GFP_RETRY_MAYFAIL", "R" }, 645 { "__GFP_RETRY_MAYFAIL", "R" },
647 { "__GFP_NOFAIL", "NF" }, 646 { "__GFP_NOFAIL", "NF" },
@@ -655,7 +654,6 @@ static const struct {
655 { "__GFP_RECLAIMABLE", "RC" }, 654 { "__GFP_RECLAIMABLE", "RC" },
656 { "__GFP_MOVABLE", "M" }, 655 { "__GFP_MOVABLE", "M" },
657 { "__GFP_ACCOUNT", "AC" }, 656 { "__GFP_ACCOUNT", "AC" },
658 { "__GFP_NOTRACK", "NT" },
659 { "__GFP_WRITE", "WR" }, 657 { "__GFP_WRITE", "WR" },
660 { "__GFP_RECLAIM", "R" }, 658 { "__GFP_RECLAIM", "R" },
661 { "__GFP_DIRECT_RECLAIM", "DR" }, 659 { "__GFP_DIRECT_RECLAIM", "DR" },