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/selftests | |
| 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/selftests')
| -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 | } | ||
