diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-07 11:50:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-07 11:50:34 -0400 |
commit | f536b3cae84eb7c9f3495285ad048d13a397ed0b (patch) | |
tree | b53eee1c45eb080168786e2f103e76d6706cbbb0 /tools/testing | |
parent | e669830526a0abaf301bf408df69cde33901ac63 (diff) | |
parent | 537e5400a0a05c4efe70e7b372c19cfcd0179362 (diff) |
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
Pull powerpc updates from Ben Herrenschmidt:
"This is the powerpc new goodies for 3.17. The short story:
The biggest bit is Michael removing all of pre-POWER4 processor
support from the 64-bit kernel. POWER3 and rs64. This gets rid of a
ton of old cruft that has been bitrotting in a long while. It was
broken for quite a few versions already and nobody noticed. Nobody
uses those machines anymore. While at it, he cleaned up a bunch of
old dusty cabinets, getting rid of a skeletton or two.
Then, we have some base VFIO support for KVM, which allows assigning
of PCI devices to KVM guests, support for large 64-bit BARs on
"powernv" platforms, support for HMI (Hardware Management Interrupts)
on those same platforms, some sparse-vmemmap improvements (for memory
hotplug),
There is the usual batch of Freescale embedded updates (summary in the
merge commit) and fixes here or there, I think that's it for the
highlights"
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (102 commits)
powerpc/eeh: Export eeh_iommu_group_to_pe()
powerpc/eeh: Add missing #ifdef CONFIG_IOMMU_API
powerpc: Reduce scariness of interrupt frames in stack traces
powerpc: start loop at section start of start in vmemmap_populated()
powerpc: implement vmemmap_free()
powerpc: implement vmemmap_remove_mapping() for BOOK3S
powerpc: implement vmemmap_list_free()
powerpc: Fail remap_4k_pfn() if PFN doesn't fit inside PTE
powerpc/book3s: Fix endianess issue for HMI handling on napping cpus.
powerpc/book3s: handle HMIs for cpus in nap mode.
powerpc/powernv: Invoke opal call to handle hmi.
powerpc/book3s: Add basic infrastructure to handle HMI in Linux.
powerpc/iommu: Fix comments with it_page_shift
powerpc/powernv: Handle compound PE in config accessors
powerpc/powernv: Handle compound PE for EEH
powerpc/powernv: Handle compound PE
powerpc/powernv: Split ioda_eeh_get_state()
powerpc/powernv: Allow to freeze PE
powerpc/powernv: Enable M64 aperatus for PHB3
powerpc/eeh: Aux PE data for error log
...
Diffstat (limited to 'tools/testing')
-rw-r--r-- | tools/testing/selftests/powerpc/Makefile | 10 | ||||
-rw-r--r-- | tools/testing/selftests/powerpc/pmu/Makefile | 19 | ||||
-rw-r--r-- | tools/testing/selftests/powerpc/pmu/count_instructions.c | 30 | ||||
-rw-r--r-- | tools/testing/selftests/powerpc/pmu/ebb/Makefile | 5 | ||||
-rw-r--r-- | tools/testing/selftests/powerpc/pmu/ebb/busy_loop.S | 271 | ||||
-rw-r--r-- | tools/testing/selftests/powerpc/pmu/ebb/cycles_with_mmcr2_test.c | 91 | ||||
-rw-r--r-- | tools/testing/selftests/powerpc/pmu/ebb/ebb.c | 261 | ||||
-rw-r--r-- | tools/testing/selftests/powerpc/pmu/ebb/ebb.h | 1 | ||||
-rw-r--r-- | tools/testing/selftests/powerpc/pmu/l3_bank_test.c | 48 | ||||
-rw-r--r-- | tools/testing/selftests/powerpc/pmu/lib.c | 50 | ||||
-rw-r--r-- | tools/testing/selftests/powerpc/pmu/lib.h | 1 | ||||
-rw-r--r-- | tools/testing/selftests/powerpc/pmu/per_event_excludes.c | 114 |
12 files changed, 617 insertions, 284 deletions
diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile index 54833a791a44..74a78cedce37 100644 --- a/tools/testing/selftests/powerpc/Makefile +++ b/tools/testing/selftests/powerpc/Makefile | |||
@@ -17,10 +17,10 @@ TARGETS = pmu copyloops mm tm | |||
17 | 17 | ||
18 | endif | 18 | endif |
19 | 19 | ||
20 | all: | 20 | all: $(TARGETS) |
21 | @for TARGET in $(TARGETS); do \ | 21 | |
22 | $(MAKE) -C $$TARGET all; \ | 22 | $(TARGETS): |
23 | done; | 23 | $(MAKE) -k -C $@ all |
24 | 24 | ||
25 | run_tests: all | 25 | run_tests: all |
26 | @for TARGET in $(TARGETS); do \ | 26 | @for TARGET in $(TARGETS); do \ |
@@ -36,4 +36,4 @@ clean: | |||
36 | tags: | 36 | tags: |
37 | find . -name '*.c' -o -name '*.h' | xargs ctags | 37 | find . -name '*.c' -o -name '*.h' | xargs ctags |
38 | 38 | ||
39 | .PHONY: all run_tests clean tags | 39 | .PHONY: all run_tests clean tags $(TARGETS) |
diff --git a/tools/testing/selftests/powerpc/pmu/Makefile b/tools/testing/selftests/powerpc/pmu/Makefile index b9ff0db42c79..c9f4263906a5 100644 --- a/tools/testing/selftests/powerpc/pmu/Makefile +++ b/tools/testing/selftests/powerpc/pmu/Makefile | |||
@@ -1,10 +1,12 @@ | |||
1 | noarg: | 1 | noarg: |
2 | $(MAKE) -C ../ | 2 | $(MAKE) -C ../ |
3 | 3 | ||
4 | PROGS := count_instructions | 4 | PROGS := count_instructions l3_bank_test per_event_excludes |
5 | EXTRA_SOURCES := ../harness.c event.c | 5 | EXTRA_SOURCES := ../harness.c event.c lib.c |
6 | 6 | ||
7 | all: $(PROGS) sub_all | 7 | SUB_TARGETS = ebb |
8 | |||
9 | all: $(PROGS) $(SUB_TARGETS) | ||
8 | 10 | ||
9 | $(PROGS): $(EXTRA_SOURCES) | 11 | $(PROGS): $(EXTRA_SOURCES) |
10 | 12 | ||
@@ -20,13 +22,8 @@ run_tests: all sub_run_tests | |||
20 | clean: sub_clean | 22 | clean: sub_clean |
21 | rm -f $(PROGS) loop.o | 23 | rm -f $(PROGS) loop.o |
22 | 24 | ||
23 | 25 | $(SUB_TARGETS): | |
24 | SUB_TARGETS = ebb | 26 | $(MAKE) -k -C $@ all |
25 | |||
26 | sub_all: | ||
27 | @for TARGET in $(SUB_TARGETS); do \ | ||
28 | $(MAKE) -C $$TARGET all; \ | ||
29 | done; | ||
30 | 27 | ||
31 | sub_run_tests: all | 28 | sub_run_tests: all |
32 | @for TARGET in $(SUB_TARGETS); do \ | 29 | @for TARGET in $(SUB_TARGETS); do \ |
@@ -38,4 +35,4 @@ sub_clean: | |||
38 | $(MAKE) -C $$TARGET clean; \ | 35 | $(MAKE) -C $$TARGET clean; \ |
39 | done; | 36 | done; |
40 | 37 | ||
41 | .PHONY: all run_tests clean sub_all sub_run_tests sub_clean | 38 | .PHONY: all run_tests clean sub_run_tests sub_clean $(SUB_TARGETS) |
diff --git a/tools/testing/selftests/powerpc/pmu/count_instructions.c b/tools/testing/selftests/powerpc/pmu/count_instructions.c index 312b4f0fd27c..4622117b24c0 100644 --- a/tools/testing/selftests/powerpc/pmu/count_instructions.c +++ b/tools/testing/selftests/powerpc/pmu/count_instructions.c | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | #include "event.h" | 13 | #include "event.h" |
14 | #include "utils.h" | 14 | #include "utils.h" |
15 | #include "lib.h" | ||
15 | 16 | ||
16 | extern void thirty_two_instruction_loop(u64 loops); | 17 | extern void thirty_two_instruction_loop(u64 loops); |
17 | 18 | ||
@@ -90,7 +91,7 @@ static u64 determine_overhead(struct event *events) | |||
90 | return overhead; | 91 | return overhead; |
91 | } | 92 | } |
92 | 93 | ||
93 | static int count_instructions(void) | 94 | static int test_body(void) |
94 | { | 95 | { |
95 | struct event events[2]; | 96 | struct event events[2]; |
96 | u64 overhead; | 97 | u64 overhead; |
@@ -111,17 +112,23 @@ static int count_instructions(void) | |||
111 | overhead = determine_overhead(events); | 112 | overhead = determine_overhead(events); |
112 | printf("Overhead of null loop: %llu instructions\n", overhead); | 113 | printf("Overhead of null loop: %llu instructions\n", overhead); |
113 | 114 | ||
114 | /* Run for 1M instructions */ | 115 | /* Run for 1Mi instructions */ |
115 | FAIL_IF(do_count_loop(events, 0x100000, overhead, true)); | 116 | FAIL_IF(do_count_loop(events, 1000000, overhead, true)); |
117 | |||
118 | /* Run for 10Mi instructions */ | ||
119 | FAIL_IF(do_count_loop(events, 10000000, overhead, true)); | ||
120 | |||
121 | /* Run for 100Mi instructions */ | ||
122 | FAIL_IF(do_count_loop(events, 100000000, overhead, true)); | ||
116 | 123 | ||
117 | /* Run for 10M instructions */ | 124 | /* Run for 1Bi instructions */ |
118 | FAIL_IF(do_count_loop(events, 0xa00000, overhead, true)); | 125 | FAIL_IF(do_count_loop(events, 1000000000, overhead, true)); |
119 | 126 | ||
120 | /* Run for 100M instructions */ | 127 | /* Run for 16Bi instructions */ |
121 | FAIL_IF(do_count_loop(events, 0x6400000, overhead, true)); | 128 | FAIL_IF(do_count_loop(events, 16000000000, overhead, true)); |
122 | 129 | ||
123 | /* Run for 1G instructions */ | 130 | /* Run for 64Bi instructions */ |
124 | FAIL_IF(do_count_loop(events, 0x40000000, overhead, true)); | 131 | FAIL_IF(do_count_loop(events, 64000000000, overhead, true)); |
125 | 132 | ||
126 | event_close(&events[0]); | 133 | event_close(&events[0]); |
127 | event_close(&events[1]); | 134 | event_close(&events[1]); |
@@ -129,6 +136,11 @@ static int count_instructions(void) | |||
129 | return 0; | 136 | return 0; |
130 | } | 137 | } |
131 | 138 | ||
139 | static int count_instructions(void) | ||
140 | { | ||
141 | return eat_cpu(test_body); | ||
142 | } | ||
143 | |||
132 | int main(void) | 144 | int main(void) |
133 | { | 145 | { |
134 | return test_harness(count_instructions, "count_instructions"); | 146 | return test_harness(count_instructions, "count_instructions"); |
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/Makefile b/tools/testing/selftests/powerpc/pmu/ebb/Makefile index edbba2affc2c..3dc4332698cb 100644 --- a/tools/testing/selftests/powerpc/pmu/ebb/Makefile +++ b/tools/testing/selftests/powerpc/pmu/ebb/Makefile | |||
@@ -13,11 +13,12 @@ PROGS := reg_access_test event_attributes_test cycles_test \ | |||
13 | close_clears_pmcc_test instruction_count_test \ | 13 | close_clears_pmcc_test instruction_count_test \ |
14 | fork_cleanup_test ebb_on_child_test \ | 14 | fork_cleanup_test ebb_on_child_test \ |
15 | ebb_on_willing_child_test back_to_back_ebbs_test \ | 15 | ebb_on_willing_child_test back_to_back_ebbs_test \ |
16 | lost_exception_test no_handler_test | 16 | lost_exception_test no_handler_test \ |
17 | cycles_with_mmcr2_test | ||
17 | 18 | ||
18 | all: $(PROGS) | 19 | all: $(PROGS) |
19 | 20 | ||
20 | $(PROGS): ../../harness.c ../event.c ../lib.c ebb.c ebb_handler.S trace.c | 21 | $(PROGS): ../../harness.c ../event.c ../lib.c ebb.c ebb_handler.S trace.c busy_loop.S |
21 | 22 | ||
22 | instruction_count_test: ../loop.S | 23 | instruction_count_test: ../loop.S |
23 | 24 | ||
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/busy_loop.S b/tools/testing/selftests/powerpc/pmu/ebb/busy_loop.S new file mode 100644 index 000000000000..c7e4093f1cd3 --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/ebb/busy_loop.S | |||
@@ -0,0 +1,271 @@ | |||
1 | /* | ||
2 | * Copyright 2014, Michael Ellerman, IBM Corp. | ||
3 | * Licensed under GPLv2. | ||
4 | */ | ||
5 | |||
6 | #include <ppc-asm.h> | ||
7 | |||
8 | .text | ||
9 | |||
10 | FUNC_START(core_busy_loop) | ||
11 | stdu %r1, -168(%r1) | ||
12 | std r14, 160(%r1) | ||
13 | std r15, 152(%r1) | ||
14 | std r16, 144(%r1) | ||
15 | std r17, 136(%r1) | ||
16 | std r18, 128(%r1) | ||
17 | std r19, 120(%r1) | ||
18 | std r20, 112(%r1) | ||
19 | std r21, 104(%r1) | ||
20 | std r22, 96(%r1) | ||
21 | std r23, 88(%r1) | ||
22 | std r24, 80(%r1) | ||
23 | std r25, 72(%r1) | ||
24 | std r26, 64(%r1) | ||
25 | std r27, 56(%r1) | ||
26 | std r28, 48(%r1) | ||
27 | std r29, 40(%r1) | ||
28 | std r30, 32(%r1) | ||
29 | std r31, 24(%r1) | ||
30 | |||
31 | li r3, 0x3030 | ||
32 | std r3, -96(%r1) | ||
33 | li r4, 0x4040 | ||
34 | std r4, -104(%r1) | ||
35 | li r5, 0x5050 | ||
36 | std r5, -112(%r1) | ||
37 | li r6, 0x6060 | ||
38 | std r6, -120(%r1) | ||
39 | li r7, 0x7070 | ||
40 | std r7, -128(%r1) | ||
41 | li r8, 0x0808 | ||
42 | std r8, -136(%r1) | ||
43 | li r9, 0x0909 | ||
44 | std r9, -144(%r1) | ||
45 | li r10, 0x1010 | ||
46 | std r10, -152(%r1) | ||
47 | li r11, 0x1111 | ||
48 | std r11, -160(%r1) | ||
49 | li r14, 0x1414 | ||
50 | std r14, -168(%r1) | ||
51 | li r15, 0x1515 | ||
52 | std r15, -176(%r1) | ||
53 | li r16, 0x1616 | ||
54 | std r16, -184(%r1) | ||
55 | li r17, 0x1717 | ||
56 | std r17, -192(%r1) | ||
57 | li r18, 0x1818 | ||
58 | std r18, -200(%r1) | ||
59 | li r19, 0x1919 | ||
60 | std r19, -208(%r1) | ||
61 | li r20, 0x2020 | ||
62 | std r20, -216(%r1) | ||
63 | li r21, 0x2121 | ||
64 | std r21, -224(%r1) | ||
65 | li r22, 0x2222 | ||
66 | std r22, -232(%r1) | ||
67 | li r23, 0x2323 | ||
68 | std r23, -240(%r1) | ||
69 | li r24, 0x2424 | ||
70 | std r24, -248(%r1) | ||
71 | li r25, 0x2525 | ||
72 | std r25, -256(%r1) | ||
73 | li r26, 0x2626 | ||
74 | std r26, -264(%r1) | ||
75 | li r27, 0x2727 | ||
76 | std r27, -272(%r1) | ||
77 | li r28, 0x2828 | ||
78 | std r28, -280(%r1) | ||
79 | li r29, 0x2929 | ||
80 | std r29, -288(%r1) | ||
81 | li r30, 0x3030 | ||
82 | li r31, 0x3131 | ||
83 | |||
84 | li r3, 0 | ||
85 | 0: addi r3, r3, 1 | ||
86 | cmpwi r3, 100 | ||
87 | blt 0b | ||
88 | |||
89 | /* Return 1 (fail) unless we get through all the checks */ | ||
90 | li r3, 1 | ||
91 | |||
92 | /* Check none of our registers have been corrupted */ | ||
93 | cmpwi r4, 0x4040 | ||
94 | bne 1f | ||
95 | cmpwi r5, 0x5050 | ||
96 | bne 1f | ||
97 | cmpwi r6, 0x6060 | ||
98 | bne 1f | ||
99 | cmpwi r7, 0x7070 | ||
100 | bne 1f | ||
101 | cmpwi r8, 0x0808 | ||
102 | bne 1f | ||
103 | cmpwi r9, 0x0909 | ||
104 | bne 1f | ||
105 | cmpwi r10, 0x1010 | ||
106 | bne 1f | ||
107 | cmpwi r11, 0x1111 | ||
108 | bne 1f | ||
109 | cmpwi r14, 0x1414 | ||
110 | bne 1f | ||
111 | cmpwi r15, 0x1515 | ||
112 | bne 1f | ||
113 | cmpwi r16, 0x1616 | ||
114 | bne 1f | ||
115 | cmpwi r17, 0x1717 | ||
116 | bne 1f | ||
117 | cmpwi r18, 0x1818 | ||
118 | bne 1f | ||
119 | cmpwi r19, 0x1919 | ||
120 | bne 1f | ||
121 | cmpwi r20, 0x2020 | ||
122 | bne 1f | ||
123 | cmpwi r21, 0x2121 | ||
124 | bne 1f | ||
125 | cmpwi r22, 0x2222 | ||
126 | bne 1f | ||
127 | cmpwi r23, 0x2323 | ||
128 | bne 1f | ||
129 | cmpwi r24, 0x2424 | ||
130 | bne 1f | ||
131 | cmpwi r25, 0x2525 | ||
132 | bne 1f | ||
133 | cmpwi r26, 0x2626 | ||
134 | bne 1f | ||
135 | cmpwi r27, 0x2727 | ||
136 | bne 1f | ||
137 | cmpwi r28, 0x2828 | ||
138 | bne 1f | ||
139 | cmpwi r29, 0x2929 | ||
140 | bne 1f | ||
141 | cmpwi r30, 0x3030 | ||
142 | bne 1f | ||
143 | cmpwi r31, 0x3131 | ||
144 | bne 1f | ||
145 | |||
146 | /* Load junk into all our registers before we reload them from the stack. */ | ||
147 | li r3, 0xde | ||
148 | li r4, 0xad | ||
149 | li r5, 0xbe | ||
150 | li r6, 0xef | ||
151 | li r7, 0xde | ||
152 | li r8, 0xad | ||
153 | li r9, 0xbe | ||
154 | li r10, 0xef | ||
155 | li r11, 0xde | ||
156 | li r14, 0xad | ||
157 | li r15, 0xbe | ||
158 | li r16, 0xef | ||
159 | li r17, 0xde | ||
160 | li r18, 0xad | ||
161 | li r19, 0xbe | ||
162 | li r20, 0xef | ||
163 | li r21, 0xde | ||
164 | li r22, 0xad | ||
165 | li r23, 0xbe | ||
166 | li r24, 0xef | ||
167 | li r25, 0xde | ||
168 | li r26, 0xad | ||
169 | li r27, 0xbe | ||
170 | li r28, 0xef | ||
171 | li r29, 0xdd | ||
172 | |||
173 | ld r3, -96(%r1) | ||
174 | cmpwi r3, 0x3030 | ||
175 | bne 1f | ||
176 | ld r4, -104(%r1) | ||
177 | cmpwi r4, 0x4040 | ||
178 | bne 1f | ||
179 | ld r5, -112(%r1) | ||
180 | cmpwi r5, 0x5050 | ||
181 | bne 1f | ||
182 | ld r6, -120(%r1) | ||
183 | cmpwi r6, 0x6060 | ||
184 | bne 1f | ||
185 | ld r7, -128(%r1) | ||
186 | cmpwi r7, 0x7070 | ||
187 | bne 1f | ||
188 | ld r8, -136(%r1) | ||
189 | cmpwi r8, 0x0808 | ||
190 | bne 1f | ||
191 | ld r9, -144(%r1) | ||
192 | cmpwi r9, 0x0909 | ||
193 | bne 1f | ||
194 | ld r10, -152(%r1) | ||
195 | cmpwi r10, 0x1010 | ||
196 | bne 1f | ||
197 | ld r11, -160(%r1) | ||
198 | cmpwi r11, 0x1111 | ||
199 | bne 1f | ||
200 | ld r14, -168(%r1) | ||
201 | cmpwi r14, 0x1414 | ||
202 | bne 1f | ||
203 | ld r15, -176(%r1) | ||
204 | cmpwi r15, 0x1515 | ||
205 | bne 1f | ||
206 | ld r16, -184(%r1) | ||
207 | cmpwi r16, 0x1616 | ||
208 | bne 1f | ||
209 | ld r17, -192(%r1) | ||
210 | cmpwi r17, 0x1717 | ||
211 | bne 1f | ||
212 | ld r18, -200(%r1) | ||
213 | cmpwi r18, 0x1818 | ||
214 | bne 1f | ||
215 | ld r19, -208(%r1) | ||
216 | cmpwi r19, 0x1919 | ||
217 | bne 1f | ||
218 | ld r20, -216(%r1) | ||
219 | cmpwi r20, 0x2020 | ||
220 | bne 1f | ||
221 | ld r21, -224(%r1) | ||
222 | cmpwi r21, 0x2121 | ||
223 | bne 1f | ||
224 | ld r22, -232(%r1) | ||
225 | cmpwi r22, 0x2222 | ||
226 | bne 1f | ||
227 | ld r23, -240(%r1) | ||
228 | cmpwi r23, 0x2323 | ||
229 | bne 1f | ||
230 | ld r24, -248(%r1) | ||
231 | cmpwi r24, 0x2424 | ||
232 | bne 1f | ||
233 | ld r25, -256(%r1) | ||
234 | cmpwi r25, 0x2525 | ||
235 | bne 1f | ||
236 | ld r26, -264(%r1) | ||
237 | cmpwi r26, 0x2626 | ||
238 | bne 1f | ||
239 | ld r27, -272(%r1) | ||
240 | cmpwi r27, 0x2727 | ||
241 | bne 1f | ||
242 | ld r28, -280(%r1) | ||
243 | cmpwi r28, 0x2828 | ||
244 | bne 1f | ||
245 | ld r29, -288(%r1) | ||
246 | cmpwi r29, 0x2929 | ||
247 | bne 1f | ||
248 | |||
249 | /* Load 0 (success) to return */ | ||
250 | li r3, 0 | ||
251 | |||
252 | 1: ld r14, 160(%r1) | ||
253 | ld r15, 152(%r1) | ||
254 | ld r16, 144(%r1) | ||
255 | ld r17, 136(%r1) | ||
256 | ld r18, 128(%r1) | ||
257 | ld r19, 120(%r1) | ||
258 | ld r20, 112(%r1) | ||
259 | ld r21, 104(%r1) | ||
260 | ld r22, 96(%r1) | ||
261 | ld r23, 88(%r1) | ||
262 | ld r24, 80(%r1) | ||
263 | ld r25, 72(%r1) | ||
264 | ld r26, 64(%r1) | ||
265 | ld r27, 56(%r1) | ||
266 | ld r28, 48(%r1) | ||
267 | ld r29, 40(%r1) | ||
268 | ld r30, 32(%r1) | ||
269 | ld r31, 24(%r1) | ||
270 | addi %r1, %r1, 168 | ||
271 | blr | ||
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/cycles_with_mmcr2_test.c b/tools/testing/selftests/powerpc/pmu/ebb/cycles_with_mmcr2_test.c new file mode 100644 index 000000000000..d43029b0800c --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/ebb/cycles_with_mmcr2_test.c | |||
@@ -0,0 +1,91 @@ | |||
1 | /* | ||
2 | * Copyright 2014, Michael Ellerman, IBM Corp. | ||
3 | * Licensed under GPLv2. | ||
4 | */ | ||
5 | |||
6 | #include <stdio.h> | ||
7 | #include <stdlib.h> | ||
8 | #include <stdbool.h> | ||
9 | |||
10 | #include "ebb.h" | ||
11 | |||
12 | |||
13 | /* | ||
14 | * Test of counting cycles while manipulating the user accessible bits in MMCR2. | ||
15 | */ | ||
16 | |||
17 | /* We use two values because the first freezes PMC1 and so we would get no EBBs */ | ||
18 | #define MMCR2_EXPECTED_1 0x4020100804020000UL /* (FC1P|FC2P|FC3P|FC4P|FC5P|FC6P) */ | ||
19 | #define MMCR2_EXPECTED_2 0x0020100804020000UL /* ( FC2P|FC3P|FC4P|FC5P|FC6P) */ | ||
20 | |||
21 | |||
22 | int cycles_with_mmcr2(void) | ||
23 | { | ||
24 | struct event event; | ||
25 | uint64_t val, expected[2], actual; | ||
26 | int i; | ||
27 | bool bad_mmcr2; | ||
28 | |||
29 | event_init_named(&event, 0x1001e, "cycles"); | ||
30 | event_leader_ebb_init(&event); | ||
31 | |||
32 | event.attr.exclude_kernel = 1; | ||
33 | event.attr.exclude_hv = 1; | ||
34 | event.attr.exclude_idle = 1; | ||
35 | |||
36 | FAIL_IF(event_open(&event)); | ||
37 | |||
38 | ebb_enable_pmc_counting(1); | ||
39 | setup_ebb_handler(standard_ebb_callee); | ||
40 | ebb_global_enable(); | ||
41 | |||
42 | FAIL_IF(ebb_event_enable(&event)); | ||
43 | |||
44 | mtspr(SPRN_PMC1, pmc_sample_period(sample_period)); | ||
45 | |||
46 | /* XXX Set of MMCR2 must be after enable */ | ||
47 | expected[0] = MMCR2_EXPECTED_1; | ||
48 | expected[1] = MMCR2_EXPECTED_2; | ||
49 | i = 0; | ||
50 | bad_mmcr2 = false; | ||
51 | |||
52 | /* Make sure we loop until we take at least one EBB */ | ||
53 | while ((ebb_state.stats.ebb_count < 20 && !bad_mmcr2) || | ||
54 | ebb_state.stats.ebb_count < 1) | ||
55 | { | ||
56 | mtspr(SPRN_MMCR2, expected[i % 2]); | ||
57 | |||
58 | FAIL_IF(core_busy_loop()); | ||
59 | |||
60 | val = mfspr(SPRN_MMCR2); | ||
61 | if (val != expected[i % 2]) { | ||
62 | bad_mmcr2 = true; | ||
63 | actual = val; | ||
64 | } | ||
65 | |||
66 | i++; | ||
67 | } | ||
68 | |||
69 | ebb_global_disable(); | ||
70 | ebb_freeze_pmcs(); | ||
71 | |||
72 | count_pmc(1, sample_period); | ||
73 | |||
74 | dump_ebb_state(); | ||
75 | |||
76 | event_close(&event); | ||
77 | |||
78 | FAIL_IF(ebb_state.stats.ebb_count == 0); | ||
79 | |||
80 | if (bad_mmcr2) | ||
81 | printf("Bad MMCR2 value seen is 0x%lx\n", actual); | ||
82 | |||
83 | FAIL_IF(bad_mmcr2); | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | int main(void) | ||
89 | { | ||
90 | return test_harness(cycles_with_mmcr2, "cycles_with_mmcr2"); | ||
91 | } | ||
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/ebb.c b/tools/testing/selftests/powerpc/pmu/ebb/ebb.c index 1b46be94b64c..d7a72ce696b5 100644 --- a/tools/testing/selftests/powerpc/pmu/ebb/ebb.c +++ b/tools/testing/selftests/powerpc/pmu/ebb/ebb.c | |||
@@ -224,6 +224,7 @@ void dump_ebb_hw_state(void) | |||
224 | 224 | ||
225 | printf("HW state:\n" \ | 225 | printf("HW state:\n" \ |
226 | "MMCR0 0x%016x %s\n" \ | 226 | "MMCR0 0x%016x %s\n" \ |
227 | "MMCR2 0x%016lx\n" \ | ||
227 | "EBBHR 0x%016lx\n" \ | 228 | "EBBHR 0x%016lx\n" \ |
228 | "BESCR 0x%016llx %s\n" \ | 229 | "BESCR 0x%016llx %s\n" \ |
229 | "PMC1 0x%016lx\n" \ | 230 | "PMC1 0x%016lx\n" \ |
@@ -233,10 +234,11 @@ void dump_ebb_hw_state(void) | |||
233 | "PMC5 0x%016lx\n" \ | 234 | "PMC5 0x%016lx\n" \ |
234 | "PMC6 0x%016lx\n" \ | 235 | "PMC6 0x%016lx\n" \ |
235 | "SIAR 0x%016lx\n", | 236 | "SIAR 0x%016lx\n", |
236 | mmcr0, decode_mmcr0(mmcr0), mfspr(SPRN_EBBHR), bescr, | 237 | mmcr0, decode_mmcr0(mmcr0), mfspr(SPRN_MMCR2), |
237 | decode_bescr(bescr), mfspr(SPRN_PMC1), mfspr(SPRN_PMC2), | 238 | mfspr(SPRN_EBBHR), bescr, decode_bescr(bescr), |
238 | mfspr(SPRN_PMC3), mfspr(SPRN_PMC4), mfspr(SPRN_PMC5), | 239 | mfspr(SPRN_PMC1), mfspr(SPRN_PMC2), mfspr(SPRN_PMC3), |
239 | mfspr(SPRN_PMC6), mfspr(SPRN_SIAR)); | 240 | mfspr(SPRN_PMC4), mfspr(SPRN_PMC5), mfspr(SPRN_PMC6), |
241 | mfspr(SPRN_SIAR)); | ||
240 | } | 242 | } |
241 | 243 | ||
242 | void dump_ebb_state(void) | 244 | void dump_ebb_state(void) |
@@ -335,257 +337,6 @@ void event_leader_ebb_init(struct event *e) | |||
335 | e->attr.pinned = 1; | 337 | e->attr.pinned = 1; |
336 | } | 338 | } |
337 | 339 | ||
338 | int core_busy_loop(void) | ||
339 | { | ||
340 | int rc; | ||
341 | |||
342 | asm volatile ( | ||
343 | "li 3, 0x3030\n" | ||
344 | "std 3, -96(1)\n" | ||
345 | "li 4, 0x4040\n" | ||
346 | "std 4, -104(1)\n" | ||
347 | "li 5, 0x5050\n" | ||
348 | "std 5, -112(1)\n" | ||
349 | "li 6, 0x6060\n" | ||
350 | "std 6, -120(1)\n" | ||
351 | "li 7, 0x7070\n" | ||
352 | "std 7, -128(1)\n" | ||
353 | "li 8, 0x0808\n" | ||
354 | "std 8, -136(1)\n" | ||
355 | "li 9, 0x0909\n" | ||
356 | "std 9, -144(1)\n" | ||
357 | "li 10, 0x1010\n" | ||
358 | "std 10, -152(1)\n" | ||
359 | "li 11, 0x1111\n" | ||
360 | "std 11, -160(1)\n" | ||
361 | "li 14, 0x1414\n" | ||
362 | "std 14, -168(1)\n" | ||
363 | "li 15, 0x1515\n" | ||
364 | "std 15, -176(1)\n" | ||
365 | "li 16, 0x1616\n" | ||
366 | "std 16, -184(1)\n" | ||
367 | "li 17, 0x1717\n" | ||
368 | "std 17, -192(1)\n" | ||
369 | "li 18, 0x1818\n" | ||
370 | "std 18, -200(1)\n" | ||
371 | "li 19, 0x1919\n" | ||
372 | "std 19, -208(1)\n" | ||
373 | "li 20, 0x2020\n" | ||
374 | "std 20, -216(1)\n" | ||
375 | "li 21, 0x2121\n" | ||
376 | "std 21, -224(1)\n" | ||
377 | "li 22, 0x2222\n" | ||
378 | "std 22, -232(1)\n" | ||
379 | "li 23, 0x2323\n" | ||
380 | "std 23, -240(1)\n" | ||
381 | "li 24, 0x2424\n" | ||
382 | "std 24, -248(1)\n" | ||
383 | "li 25, 0x2525\n" | ||
384 | "std 25, -256(1)\n" | ||
385 | "li 26, 0x2626\n" | ||
386 | "std 26, -264(1)\n" | ||
387 | "li 27, 0x2727\n" | ||
388 | "std 27, -272(1)\n" | ||
389 | "li 28, 0x2828\n" | ||
390 | "std 28, -280(1)\n" | ||
391 | "li 29, 0x2929\n" | ||
392 | "std 29, -288(1)\n" | ||
393 | "li 30, 0x3030\n" | ||
394 | "li 31, 0x3131\n" | ||
395 | |||
396 | "li 3, 0\n" | ||
397 | "0: " | ||
398 | "addi 3, 3, 1\n" | ||
399 | "cmpwi 3, 100\n" | ||
400 | "blt 0b\n" | ||
401 | |||
402 | /* Return 1 (fail) unless we get through all the checks */ | ||
403 | "li 0, 1\n" | ||
404 | |||
405 | /* Check none of our registers have been corrupted */ | ||
406 | "cmpwi 4, 0x4040\n" | ||
407 | "bne 1f\n" | ||
408 | "cmpwi 5, 0x5050\n" | ||
409 | "bne 1f\n" | ||
410 | "cmpwi 6, 0x6060\n" | ||
411 | "bne 1f\n" | ||
412 | "cmpwi 7, 0x7070\n" | ||
413 | "bne 1f\n" | ||
414 | "cmpwi 8, 0x0808\n" | ||
415 | "bne 1f\n" | ||
416 | "cmpwi 9, 0x0909\n" | ||
417 | "bne 1f\n" | ||
418 | "cmpwi 10, 0x1010\n" | ||
419 | "bne 1f\n" | ||
420 | "cmpwi 11, 0x1111\n" | ||
421 | "bne 1f\n" | ||
422 | "cmpwi 14, 0x1414\n" | ||
423 | "bne 1f\n" | ||
424 | "cmpwi 15, 0x1515\n" | ||
425 | "bne 1f\n" | ||
426 | "cmpwi 16, 0x1616\n" | ||
427 | "bne 1f\n" | ||
428 | "cmpwi 17, 0x1717\n" | ||
429 | "bne 1f\n" | ||
430 | "cmpwi 18, 0x1818\n" | ||
431 | "bne 1f\n" | ||
432 | "cmpwi 19, 0x1919\n" | ||
433 | "bne 1f\n" | ||
434 | "cmpwi 20, 0x2020\n" | ||
435 | "bne 1f\n" | ||
436 | "cmpwi 21, 0x2121\n" | ||
437 | "bne 1f\n" | ||
438 | "cmpwi 22, 0x2222\n" | ||
439 | "bne 1f\n" | ||
440 | "cmpwi 23, 0x2323\n" | ||
441 | "bne 1f\n" | ||
442 | "cmpwi 24, 0x2424\n" | ||
443 | "bne 1f\n" | ||
444 | "cmpwi 25, 0x2525\n" | ||
445 | "bne 1f\n" | ||
446 | "cmpwi 26, 0x2626\n" | ||
447 | "bne 1f\n" | ||
448 | "cmpwi 27, 0x2727\n" | ||
449 | "bne 1f\n" | ||
450 | "cmpwi 28, 0x2828\n" | ||
451 | "bne 1f\n" | ||
452 | "cmpwi 29, 0x2929\n" | ||
453 | "bne 1f\n" | ||
454 | "cmpwi 30, 0x3030\n" | ||
455 | "bne 1f\n" | ||
456 | "cmpwi 31, 0x3131\n" | ||
457 | "bne 1f\n" | ||
458 | |||
459 | /* Load junk into all our registers before we reload them from the stack. */ | ||
460 | "li 3, 0xde\n" | ||
461 | "li 4, 0xad\n" | ||
462 | "li 5, 0xbe\n" | ||
463 | "li 6, 0xef\n" | ||
464 | "li 7, 0xde\n" | ||
465 | "li 8, 0xad\n" | ||
466 | "li 9, 0xbe\n" | ||
467 | "li 10, 0xef\n" | ||
468 | "li 11, 0xde\n" | ||
469 | "li 14, 0xad\n" | ||
470 | "li 15, 0xbe\n" | ||
471 | "li 16, 0xef\n" | ||
472 | "li 17, 0xde\n" | ||
473 | "li 18, 0xad\n" | ||
474 | "li 19, 0xbe\n" | ||
475 | "li 20, 0xef\n" | ||
476 | "li 21, 0xde\n" | ||
477 | "li 22, 0xad\n" | ||
478 | "li 23, 0xbe\n" | ||
479 | "li 24, 0xef\n" | ||
480 | "li 25, 0xde\n" | ||
481 | "li 26, 0xad\n" | ||
482 | "li 27, 0xbe\n" | ||
483 | "li 28, 0xef\n" | ||
484 | "li 29, 0xdd\n" | ||
485 | |||
486 | "ld 3, -96(1)\n" | ||
487 | "cmpwi 3, 0x3030\n" | ||
488 | "bne 1f\n" | ||
489 | "ld 4, -104(1)\n" | ||
490 | "cmpwi 4, 0x4040\n" | ||
491 | "bne 1f\n" | ||
492 | "ld 5, -112(1)\n" | ||
493 | "cmpwi 5, 0x5050\n" | ||
494 | "bne 1f\n" | ||
495 | "ld 6, -120(1)\n" | ||
496 | "cmpwi 6, 0x6060\n" | ||
497 | "bne 1f\n" | ||
498 | "ld 7, -128(1)\n" | ||
499 | "cmpwi 7, 0x7070\n" | ||
500 | "bne 1f\n" | ||
501 | "ld 8, -136(1)\n" | ||
502 | "cmpwi 8, 0x0808\n" | ||
503 | "bne 1f\n" | ||
504 | "ld 9, -144(1)\n" | ||
505 | "cmpwi 9, 0x0909\n" | ||
506 | "bne 1f\n" | ||
507 | "ld 10, -152(1)\n" | ||
508 | "cmpwi 10, 0x1010\n" | ||
509 | "bne 1f\n" | ||
510 | "ld 11, -160(1)\n" | ||
511 | "cmpwi 11, 0x1111\n" | ||
512 | "bne 1f\n" | ||
513 | "ld 14, -168(1)\n" | ||
514 | "cmpwi 14, 0x1414\n" | ||
515 | "bne 1f\n" | ||
516 | "ld 15, -176(1)\n" | ||
517 | "cmpwi 15, 0x1515\n" | ||
518 | "bne 1f\n" | ||
519 | "ld 16, -184(1)\n" | ||
520 | "cmpwi 16, 0x1616\n" | ||
521 | "bne 1f\n" | ||
522 | "ld 17, -192(1)\n" | ||
523 | "cmpwi 17, 0x1717\n" | ||
524 | "bne 1f\n" | ||
525 | "ld 18, -200(1)\n" | ||
526 | "cmpwi 18, 0x1818\n" | ||
527 | "bne 1f\n" | ||
528 | "ld 19, -208(1)\n" | ||
529 | "cmpwi 19, 0x1919\n" | ||
530 | "bne 1f\n" | ||
531 | "ld 20, -216(1)\n" | ||
532 | "cmpwi 20, 0x2020\n" | ||
533 | "bne 1f\n" | ||
534 | "ld 21, -224(1)\n" | ||
535 | "cmpwi 21, 0x2121\n" | ||
536 | "bne 1f\n" | ||
537 | "ld 22, -232(1)\n" | ||
538 | "cmpwi 22, 0x2222\n" | ||
539 | "bne 1f\n" | ||
540 | "ld 23, -240(1)\n" | ||
541 | "cmpwi 23, 0x2323\n" | ||
542 | "bne 1f\n" | ||
543 | "ld 24, -248(1)\n" | ||
544 | "cmpwi 24, 0x2424\n" | ||
545 | "bne 1f\n" | ||
546 | "ld 25, -256(1)\n" | ||
547 | "cmpwi 25, 0x2525\n" | ||
548 | "bne 1f\n" | ||
549 | "ld 26, -264(1)\n" | ||
550 | "cmpwi 26, 0x2626\n" | ||
551 | "bne 1f\n" | ||
552 | "ld 27, -272(1)\n" | ||
553 | "cmpwi 27, 0x2727\n" | ||
554 | "bne 1f\n" | ||
555 | "ld 28, -280(1)\n" | ||
556 | "cmpwi 28, 0x2828\n" | ||
557 | "bne 1f\n" | ||
558 | "ld 29, -288(1)\n" | ||
559 | "cmpwi 29, 0x2929\n" | ||
560 | "bne 1f\n" | ||
561 | |||
562 | /* Load 0 (success) to return */ | ||
563 | "li 0, 0\n" | ||
564 | |||
565 | "1: mr %0, 0\n" | ||
566 | |||
567 | : "=r" (rc) | ||
568 | : /* no inputs */ | ||
569 | : "3", "4", "5", "6", "7", "8", "9", "10", "11", "14", | ||
570 | "15", "16", "17", "18", "19", "20", "21", "22", "23", | ||
571 | "24", "25", "26", "27", "28", "29", "30", "31", | ||
572 | "memory" | ||
573 | ); | ||
574 | |||
575 | return rc; | ||
576 | } | ||
577 | |||
578 | int core_busy_loop_with_freeze(void) | ||
579 | { | ||
580 | int rc; | ||
581 | |||
582 | mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~MMCR0_FC); | ||
583 | rc = core_busy_loop(); | ||
584 | mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) | MMCR0_FC); | ||
585 | |||
586 | return rc; | ||
587 | } | ||
588 | |||
589 | int ebb_child(union pipe read_pipe, union pipe write_pipe) | 340 | int ebb_child(union pipe read_pipe, union pipe write_pipe) |
590 | { | 341 | { |
591 | struct event event; | 342 | struct event event; |
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/ebb.h b/tools/testing/selftests/powerpc/pmu/ebb/ebb.h index e62bde05bf78..e44eee5d97ca 100644 --- a/tools/testing/selftests/powerpc/pmu/ebb/ebb.h +++ b/tools/testing/selftests/powerpc/pmu/ebb/ebb.h | |||
@@ -70,7 +70,6 @@ int ebb_check_mmcr0(void); | |||
70 | extern u64 sample_period; | 70 | extern u64 sample_period; |
71 | 71 | ||
72 | int core_busy_loop(void); | 72 | int core_busy_loop(void); |
73 | int core_busy_loop_with_freeze(void); | ||
74 | int ebb_child(union pipe read_pipe, union pipe write_pipe); | 73 | int ebb_child(union pipe read_pipe, union pipe write_pipe); |
75 | int catch_sigill(void (*func)(void)); | 74 | int catch_sigill(void (*func)(void)); |
76 | void write_pmc1(void); | 75 | void write_pmc1(void); |
diff --git a/tools/testing/selftests/powerpc/pmu/l3_bank_test.c b/tools/testing/selftests/powerpc/pmu/l3_bank_test.c new file mode 100644 index 000000000000..77472f31441e --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/l3_bank_test.c | |||
@@ -0,0 +1,48 @@ | |||
1 | /* | ||
2 | * Copyright 2014, Michael Ellerman, IBM Corp. | ||
3 | * Licensed under GPLv2. | ||
4 | */ | ||
5 | |||
6 | #include <stdio.h> | ||
7 | #include <stdlib.h> | ||
8 | |||
9 | #include "event.h" | ||
10 | #include "utils.h" | ||
11 | |||
12 | #define MALLOC_SIZE (0x10000 * 10) /* Ought to be enough .. */ | ||
13 | |||
14 | /* | ||
15 | * Tests that the L3 bank handling is correct. We fixed it in commit e9aaac1. | ||
16 | */ | ||
17 | static int l3_bank_test(void) | ||
18 | { | ||
19 | struct event event; | ||
20 | char *p; | ||
21 | int i; | ||
22 | |||
23 | p = malloc(MALLOC_SIZE); | ||
24 | FAIL_IF(!p); | ||
25 | |||
26 | event_init(&event, 0x84918F); | ||
27 | |||
28 | FAIL_IF(event_open(&event)); | ||
29 | |||
30 | for (i = 0; i < MALLOC_SIZE; i += 0x10000) | ||
31 | p[i] = i; | ||
32 | |||
33 | event_read(&event); | ||
34 | event_report(&event); | ||
35 | |||
36 | FAIL_IF(event.result.running == 0); | ||
37 | FAIL_IF(event.result.enabled == 0); | ||
38 | |||
39 | event_close(&event); | ||
40 | free(p); | ||
41 | |||
42 | return 0; | ||
43 | } | ||
44 | |||
45 | int main(void) | ||
46 | { | ||
47 | return test_harness(l3_bank_test, "l3_bank_test"); | ||
48 | } | ||
diff --git a/tools/testing/selftests/powerpc/pmu/lib.c b/tools/testing/selftests/powerpc/pmu/lib.c index 0f6a4731d546..9768dea37bf3 100644 --- a/tools/testing/selftests/powerpc/pmu/lib.c +++ b/tools/testing/selftests/powerpc/pmu/lib.c | |||
@@ -5,10 +5,15 @@ | |||
5 | 5 | ||
6 | #define _GNU_SOURCE /* For CPU_ZERO etc. */ | 6 | #define _GNU_SOURCE /* For CPU_ZERO etc. */ |
7 | 7 | ||
8 | #include <elf.h> | ||
8 | #include <errno.h> | 9 | #include <errno.h> |
10 | #include <fcntl.h> | ||
11 | #include <link.h> | ||
9 | #include <sched.h> | 12 | #include <sched.h> |
10 | #include <setjmp.h> | 13 | #include <setjmp.h> |
11 | #include <stdlib.h> | 14 | #include <stdlib.h> |
15 | #include <sys/stat.h> | ||
16 | #include <sys/types.h> | ||
12 | #include <sys/wait.h> | 17 | #include <sys/wait.h> |
13 | 18 | ||
14 | #include "utils.h" | 19 | #include "utils.h" |
@@ -177,8 +182,8 @@ struct addr_range libc, vdso; | |||
177 | 182 | ||
178 | int parse_proc_maps(void) | 183 | int parse_proc_maps(void) |
179 | { | 184 | { |
185 | unsigned long start, end; | ||
180 | char execute, name[128]; | 186 | char execute, name[128]; |
181 | uint64_t start, end; | ||
182 | FILE *f; | 187 | FILE *f; |
183 | int rc; | 188 | int rc; |
184 | 189 | ||
@@ -250,3 +255,46 @@ out_close: | |||
250 | out: | 255 | out: |
251 | return rc; | 256 | return rc; |
252 | } | 257 | } |
258 | |||
259 | static char auxv[4096]; | ||
260 | |||
261 | void *get_auxv_entry(int type) | ||
262 | { | ||
263 | ElfW(auxv_t) *p; | ||
264 | void *result; | ||
265 | ssize_t num; | ||
266 | int fd; | ||
267 | |||
268 | fd = open("/proc/self/auxv", O_RDONLY); | ||
269 | if (fd == -1) { | ||
270 | perror("open"); | ||
271 | return NULL; | ||
272 | } | ||
273 | |||
274 | result = NULL; | ||
275 | |||
276 | num = read(fd, auxv, sizeof(auxv)); | ||
277 | if (num < 0) { | ||
278 | perror("read"); | ||
279 | goto out; | ||
280 | } | ||
281 | |||
282 | if (num > sizeof(auxv)) { | ||
283 | printf("Overflowed auxv buffer\n"); | ||
284 | goto out; | ||
285 | } | ||
286 | |||
287 | p = (ElfW(auxv_t) *)auxv; | ||
288 | |||
289 | while (p->a_type != AT_NULL) { | ||
290 | if (p->a_type == type) { | ||
291 | result = (void *)p->a_un.a_val; | ||
292 | break; | ||
293 | } | ||
294 | |||
295 | p++; | ||
296 | } | ||
297 | out: | ||
298 | close(fd); | ||
299 | return result; | ||
300 | } | ||
diff --git a/tools/testing/selftests/powerpc/pmu/lib.h b/tools/testing/selftests/powerpc/pmu/lib.h index ca5d72ae3be6..0f0339c8a6f6 100644 --- a/tools/testing/selftests/powerpc/pmu/lib.h +++ b/tools/testing/selftests/powerpc/pmu/lib.h | |||
@@ -29,6 +29,7 @@ extern int notify_parent(union pipe write_pipe); | |||
29 | extern int notify_parent_of_error(union pipe write_pipe); | 29 | extern int notify_parent_of_error(union pipe write_pipe); |
30 | extern pid_t eat_cpu(int (test_function)(void)); | 30 | extern pid_t eat_cpu(int (test_function)(void)); |
31 | extern bool require_paranoia_below(int level); | 31 | extern bool require_paranoia_below(int level); |
32 | extern void *get_auxv_entry(int type); | ||
32 | 33 | ||
33 | struct addr_range { | 34 | struct addr_range { |
34 | uint64_t first, last; | 35 | uint64_t first, last; |
diff --git a/tools/testing/selftests/powerpc/pmu/per_event_excludes.c b/tools/testing/selftests/powerpc/pmu/per_event_excludes.c new file mode 100644 index 000000000000..fddbbc9cae2f --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/per_event_excludes.c | |||
@@ -0,0 +1,114 @@ | |||
1 | /* | ||
2 | * Copyright 2014, Michael Ellerman, IBM Corp. | ||
3 | * Licensed under GPLv2. | ||
4 | */ | ||
5 | |||
6 | #define _GNU_SOURCE | ||
7 | |||
8 | #include <elf.h> | ||
9 | #include <limits.h> | ||
10 | #include <stdio.h> | ||
11 | #include <stdbool.h> | ||
12 | #include <string.h> | ||
13 | #include <sys/prctl.h> | ||
14 | |||
15 | #include "event.h" | ||
16 | #include "lib.h" | ||
17 | #include "utils.h" | ||
18 | |||
19 | /* | ||
20 | * Test that per-event excludes work. | ||
21 | */ | ||
22 | |||
23 | static int per_event_excludes(void) | ||
24 | { | ||
25 | struct event *e, events[4]; | ||
26 | char *platform; | ||
27 | int i; | ||
28 | |||
29 | platform = (char *)get_auxv_entry(AT_BASE_PLATFORM); | ||
30 | FAIL_IF(!platform); | ||
31 | SKIP_IF(strcmp(platform, "power8") != 0); | ||
32 | |||
33 | /* | ||
34 | * We need to create the events disabled, otherwise the running/enabled | ||
35 | * counts don't match up. | ||
36 | */ | ||
37 | e = &events[0]; | ||
38 | event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS, | ||
39 | PERF_TYPE_HARDWARE, "instructions"); | ||
40 | e->attr.disabled = 1; | ||
41 | |||
42 | e = &events[1]; | ||
43 | event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS, | ||
44 | PERF_TYPE_HARDWARE, "instructions(k)"); | ||
45 | e->attr.disabled = 1; | ||
46 | e->attr.exclude_user = 1; | ||
47 | e->attr.exclude_hv = 1; | ||
48 | |||
49 | e = &events[2]; | ||
50 | event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS, | ||
51 | PERF_TYPE_HARDWARE, "instructions(h)"); | ||
52 | e->attr.disabled = 1; | ||
53 | e->attr.exclude_user = 1; | ||
54 | e->attr.exclude_kernel = 1; | ||
55 | |||
56 | e = &events[3]; | ||
57 | event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS, | ||
58 | PERF_TYPE_HARDWARE, "instructions(u)"); | ||
59 | e->attr.disabled = 1; | ||
60 | e->attr.exclude_hv = 1; | ||
61 | e->attr.exclude_kernel = 1; | ||
62 | |||
63 | FAIL_IF(event_open(&events[0])); | ||
64 | |||
65 | /* | ||
66 | * The open here will fail if we don't have per event exclude support, | ||
67 | * because the second event has an incompatible set of exclude settings | ||
68 | * and we're asking for the events to be in a group. | ||
69 | */ | ||
70 | for (i = 1; i < 4; i++) | ||
71 | FAIL_IF(event_open_with_group(&events[i], events[0].fd)); | ||
72 | |||
73 | /* | ||
74 | * Even though the above will fail without per-event excludes we keep | ||
75 | * testing in order to be thorough. | ||
76 | */ | ||
77 | prctl(PR_TASK_PERF_EVENTS_ENABLE); | ||
78 | |||
79 | /* Spin for a while */ | ||
80 | for (i = 0; i < INT_MAX; i++) | ||
81 | asm volatile("" : : : "memory"); | ||
82 | |||
83 | prctl(PR_TASK_PERF_EVENTS_DISABLE); | ||
84 | |||
85 | for (i = 0; i < 4; i++) { | ||
86 | FAIL_IF(event_read(&events[i])); | ||
87 | event_report(&events[i]); | ||
88 | } | ||
89 | |||
90 | /* | ||
91 | * We should see that all events have enabled == running. That | ||
92 | * shows that they were all on the PMU at once. | ||
93 | */ | ||
94 | for (i = 0; i < 4; i++) | ||
95 | FAIL_IF(events[i].result.running != events[i].result.enabled); | ||
96 | |||
97 | /* | ||
98 | * We can also check that the result for instructions is >= all the | ||
99 | * other counts. That's because it is counting all instructions while | ||
100 | * the others are counting a subset. | ||
101 | */ | ||
102 | for (i = 1; i < 4; i++) | ||
103 | FAIL_IF(events[0].result.value < events[i].result.value); | ||
104 | |||
105 | for (i = 0; i < 4; i++) | ||
106 | event_close(&events[i]); | ||
107 | |||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | int main(void) | ||
112 | { | ||
113 | return test_harness(per_event_excludes, "per_event_excludes"); | ||
114 | } | ||