aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-04-16 14:53:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-16 14:53:32 -0400
commitd19d5efd8c8840aa4f38a6dfbfe500d8cc27de46 (patch)
tree2e2f4f57de790c7de2ccd6d1afbec8695b2c7a46 /tools
parent34c9a0ffc75ad25b6a60f61e27c4a4b1189b8085 (diff)
parent2fe0753d49402aee325cc39c476b46fd51a8afec (diff)
Merge tag 'powerpc-4.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mpe/linux
Pull powerpc updates from Michael Ellerman: - Numerous minor fixes, cleanups etc. - More EEH work from Gavin to remove its dependency on device_nodes. - Memory hotplug implemented entirely in the kernel from Nathan Fontenot. - Removal of redundant CONFIG_PPC_OF by Kevin Hao. - Rewrite of VPHN parsing logic & tests from Greg Kurz. - A fix from Nish Aravamudan to reduce memory usage by clamping nodes_possible_map. - Support for pstore on powernv from Hari Bathini. - Removal of old powerpc specific byte swap routines by David Gibson. - Fix from Vasant Hegde to prevent the flash driver telling you it was flashing your firmware when it wasn't. - Patch from Ben Herrenschmidt to add an OPAL heartbeat driver. - Fix for an oops causing get/put_cpu_var() imbalance in perf by Jan Stancek. - Some fixes for migration from Tyrel Datwyler. - A new syscall to switch the cpu endian by Michael Ellerman. - Large series from Wei Yang to implement SRIOV, reviewed and acked by Bjorn. - A fix for the OPAL sensor driver from Cédric Le Goater. - Fixes to get STRICT_MM_TYPECHECKS building again by Michael Ellerman. - Large series from Daniel Axtens to make our PCI hooks per PHB rather than per machine. - Small patch from Sam Bobroff to explicitly abort non-suspended transactions on syscalls, plus a test to exercise it. - Numerous reworks and fixes for the 24x7 PMU from Sukadev Bhattiprolu. - Small patch to enable the hard lockup detector from Anton Blanchard. - Fix from Dave Olson for missing L2 cache information on some CPUs. - Some fixes from Michael Ellerman to get Cell machines booting again. - Freescale updates from Scott: Highlights include BMan device tree nodes, an MSI erratum workaround, a couple minor performance improvements, config updates, and misc fixes/cleanup. * tag 'powerpc-4.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mpe/linux: (196 commits) powerpc/powermac: Fix build error seen with powermac smp builds powerpc/pseries: Fix compile of memory hotplug without CONFIG_MEMORY_HOTREMOVE powerpc: Remove PPC32 code from pseries specific find_and_init_phbs() powerpc/cell: Fix iommu breakage caused by controller_ops change powerpc/eeh: Fix crash in eeh_add_device_early() on Cell powerpc/perf: Cap 64bit userspace backtraces to PERF_MAX_STACK_DEPTH powerpc/perf/hv-24x7: Fail 24x7 initcall if create_events_from_catalog() fails powerpc/pseries: Correct memory hotplug locking powerpc: Fix missing L2 cache size in /sys/devices/system/cpu powerpc: Add ppc64 hard lockup detector support oprofile: Disable oprofile NMI timer on ppc64 powerpc/perf/hv-24x7: Add missing put_cpu_var() powerpc/perf/hv-24x7: Break up single_24x7_request powerpc/perf/hv-24x7: Define update_event_count() powerpc/perf/hv-24x7: Whitespace cleanup powerpc/perf/hv-24x7: Define add_event_to_24x7_request() powerpc/perf/hv-24x7: Rename hv_24x7_event_update powerpc/perf/hv-24x7: Move debug prints to separate function powerpc/perf/hv-24x7: Drop event_24x7_request() powerpc/perf/hv-24x7: Use pr_devel() to log message ... Conflicts: tools/testing/selftests/powerpc/Makefile tools/testing/selftests/powerpc/tm/Makefile
Diffstat (limited to 'tools')
-rw-r--r--tools/testing/selftests/powerpc/Makefile16
-rw-r--r--tools/testing/selftests/powerpc/copyloops/Makefile1
-rw-r--r--tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h33
-rw-r--r--tools/testing/selftests/powerpc/harness.c47
-rw-r--r--tools/testing/selftests/powerpc/pmu/lib.c47
-rw-r--r--tools/testing/selftests/powerpc/pmu/lib.h1
-rw-r--r--tools/testing/selftests/powerpc/switch_endian/.gitignore2
-rw-r--r--tools/testing/selftests/powerpc/switch_endian/Makefile24
-rw-r--r--tools/testing/selftests/powerpc/switch_endian/check.S100
-rw-r--r--tools/testing/selftests/powerpc/switch_endian/common.h6
-rw-r--r--tools/testing/selftests/powerpc/switch_endian/switch_endian_test.S81
-rw-r--r--tools/testing/selftests/powerpc/tm/.gitignore1
-rw-r--r--tools/testing/selftests/powerpc/tm/Makefile5
-rw-r--r--tools/testing/selftests/powerpc/tm/tm-syscall-asm.S27
-rw-r--r--tools/testing/selftests/powerpc/tm/tm-syscall.c121
-rw-r--r--tools/testing/selftests/powerpc/utils.h3
-rw-r--r--tools/testing/selftests/powerpc/vphn/.gitignore1
-rw-r--r--tools/testing/selftests/powerpc/vphn/Makefile15
-rw-r--r--tools/testing/selftests/powerpc/vphn/test-vphn.c410
l---------tools/testing/selftests/powerpc/vphn/vphn.c1
l---------tools/testing/selftests/powerpc/vphn/vphn.h1
21 files changed, 852 insertions, 91 deletions
diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile
index 2958fe9a74e9..5ad042345ab9 100644
--- a/tools/testing/selftests/powerpc/Makefile
+++ b/tools/testing/selftests/powerpc/Makefile
@@ -12,37 +12,37 @@ CFLAGS := -Wall -O2 -flto -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CUR
12 12
13export CFLAGS 13export CFLAGS
14 14
15TARGETS = pmu copyloops mm tm primitives stringloops 15SUB_DIRS = pmu copyloops mm tm primitives stringloops vphn switch_endian
16 16
17endif 17endif
18 18
19all: $(TARGETS) 19all: $(SUB_DIRS)
20 20
21$(TARGETS): 21$(SUB_DIRS):
22 $(MAKE) -k -C $@ all 22 $(MAKE) -k -C $@ all
23 23
24include ../lib.mk 24include ../lib.mk
25 25
26override define RUN_TESTS 26override define RUN_TESTS
27 @for TARGET in $(TARGETS); do \ 27 @for TARGET in $(SUB_DIRS); do \
28 $(MAKE) -C $$TARGET run_tests; \ 28 $(MAKE) -C $$TARGET run_tests; \
29 done; 29 done;
30endef 30endef
31 31
32override define INSTALL_RULE 32override define INSTALL_RULE
33 @for TARGET in $(TARGETS); do \ 33 @for TARGET in $(SUB_DIRS); do \
34 $(MAKE) -C $$TARGET install; \ 34 $(MAKE) -C $$TARGET install; \
35 done; 35 done;
36endef 36endef
37 37
38override define EMIT_TESTS 38override define EMIT_TESTS
39 @for TARGET in $(TARGETS); do \ 39 @for TARGET in $(SUB_DIRS); do \
40 $(MAKE) -s -C $$TARGET emit_tests; \ 40 $(MAKE) -s -C $$TARGET emit_tests; \
41 done; 41 done;
42endef 42endef
43 43
44clean: 44clean:
45 @for TARGET in $(TARGETS); do \ 45 @for TARGET in $(SUB_DIRS); do \
46 $(MAKE) -C $$TARGET clean; \ 46 $(MAKE) -C $$TARGET clean; \
47 done; 47 done;
48 rm -f tags 48 rm -f tags
@@ -50,4 +50,4 @@ clean:
50tags: 50tags:
51 find . -name '*.c' -o -name '*.h' | xargs ctags 51 find . -name '*.c' -o -name '*.h' | xargs ctags
52 52
53.PHONY: tags $(TARGETS) 53.PHONY: tags $(SUB_DIRS)
diff --git a/tools/testing/selftests/powerpc/copyloops/Makefile b/tools/testing/selftests/powerpc/copyloops/Makefile
index c05023514ce8..384843ea0d40 100644
--- a/tools/testing/selftests/powerpc/copyloops/Makefile
+++ b/tools/testing/selftests/powerpc/copyloops/Makefile
@@ -2,6 +2,7 @@
2CFLAGS += -m64 2CFLAGS += -m64
3CFLAGS += -I$(CURDIR) 3CFLAGS += -I$(CURDIR)
4CFLAGS += -D SELFTEST 4CFLAGS += -D SELFTEST
5CFLAGS += -maltivec
5 6
6# Use our CFLAGS for the implicit .S rule 7# Use our CFLAGS for the implicit .S rule
7ASFLAGS = $(CFLAGS) 8ASFLAGS = $(CFLAGS)
diff --git a/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h b/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h
index d1dc37425510..50ae7d2091ce 100644
--- a/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h
+++ b/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h
@@ -4,39 +4,6 @@
4 4
5#define r1 1 5#define r1 1
6 6
7#define vr0 0
8#define vr1 1
9#define vr2 2
10#define vr3 3
11#define vr4 4
12#define vr5 5
13#define vr6 6
14#define vr7 7
15#define vr8 8
16#define vr9 9
17#define vr10 10
18#define vr11 11
19#define vr12 12
20#define vr13 13
21#define vr14 14
22#define vr15 15
23#define vr16 16
24#define vr17 17
25#define vr18 18
26#define vr19 19
27#define vr20 20
28#define vr21 21
29#define vr22 22
30#define vr23 23
31#define vr24 24
32#define vr25 25
33#define vr26 26
34#define vr27 27
35#define vr28 28
36#define vr29 29
37#define vr30 30
38#define vr31 31
39
40#define R14 r14 7#define R14 r14
41#define R15 r15 8#define R15 r15
42#define R16 r16 9#define R16 r16
diff --git a/tools/testing/selftests/powerpc/harness.c b/tools/testing/selftests/powerpc/harness.c
index 8ebc58a09311..f7997affd143 100644
--- a/tools/testing/selftests/powerpc/harness.c
+++ b/tools/testing/selftests/powerpc/harness.c
@@ -11,6 +11,10 @@
11#include <sys/types.h> 11#include <sys/types.h>
12#include <sys/wait.h> 12#include <sys/wait.h>
13#include <unistd.h> 13#include <unistd.h>
14#include <elf.h>
15#include <fcntl.h>
16#include <link.h>
17#include <sys/stat.h>
14 18
15#include "subunit.h" 19#include "subunit.h"
16#include "utils.h" 20#include "utils.h"
@@ -112,3 +116,46 @@ int test_harness(int (test_function)(void), char *name)
112 116
113 return rc; 117 return rc;
114} 118}
119
120static char auxv[4096];
121
122void *get_auxv_entry(int type)
123{
124 ElfW(auxv_t) *p;
125 void *result;
126 ssize_t num;
127 int fd;
128
129 fd = open("/proc/self/auxv", O_RDONLY);
130 if (fd == -1) {
131 perror("open");
132 return NULL;
133 }
134
135 result = NULL;
136
137 num = read(fd, auxv, sizeof(auxv));
138 if (num < 0) {
139 perror("read");
140 goto out;
141 }
142
143 if (num > sizeof(auxv)) {
144 printf("Overflowed auxv buffer\n");
145 goto out;
146 }
147
148 p = (ElfW(auxv_t) *)auxv;
149
150 while (p->a_type != AT_NULL) {
151 if (p->a_type == type) {
152 result = (void *)p->a_un.a_val;
153 break;
154 }
155
156 p++;
157 }
158out:
159 close(fd);
160 return result;
161}
diff --git a/tools/testing/selftests/powerpc/pmu/lib.c b/tools/testing/selftests/powerpc/pmu/lib.c
index 9768dea37bf3..a07104c2afe6 100644
--- a/tools/testing/selftests/powerpc/pmu/lib.c
+++ b/tools/testing/selftests/powerpc/pmu/lib.c
@@ -5,15 +5,10 @@
5 5
6#define _GNU_SOURCE /* For CPU_ZERO etc. */ 6#define _GNU_SOURCE /* For CPU_ZERO etc. */
7 7
8#include <elf.h>
9#include <errno.h> 8#include <errno.h>
10#include <fcntl.h>
11#include <link.h>
12#include <sched.h> 9#include <sched.h>
13#include <setjmp.h> 10#include <setjmp.h>
14#include <stdlib.h> 11#include <stdlib.h>
15#include <sys/stat.h>
16#include <sys/types.h>
17#include <sys/wait.h> 12#include <sys/wait.h>
18 13
19#include "utils.h" 14#include "utils.h"
@@ -256,45 +251,3 @@ out:
256 return rc; 251 return rc;
257} 252}
258 253
259static char auxv[4096];
260
261void *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 }
297out:
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 0f0339c8a6f6..ca5d72ae3be6 100644
--- a/tools/testing/selftests/powerpc/pmu/lib.h
+++ b/tools/testing/selftests/powerpc/pmu/lib.h
@@ -29,7 +29,6 @@ extern int notify_parent(union pipe write_pipe);
29extern int notify_parent_of_error(union pipe write_pipe); 29extern int notify_parent_of_error(union pipe write_pipe);
30extern pid_t eat_cpu(int (test_function)(void)); 30extern pid_t eat_cpu(int (test_function)(void));
31extern bool require_paranoia_below(int level); 31extern bool require_paranoia_below(int level);
32extern void *get_auxv_entry(int type);
33 32
34struct addr_range { 33struct addr_range {
35 uint64_t first, last; 34 uint64_t first, last;
diff --git a/tools/testing/selftests/powerpc/switch_endian/.gitignore b/tools/testing/selftests/powerpc/switch_endian/.gitignore
new file mode 100644
index 000000000000..89e762eab676
--- /dev/null
+++ b/tools/testing/selftests/powerpc/switch_endian/.gitignore
@@ -0,0 +1,2 @@
1switch_endian_test
2check-reversed.S
diff --git a/tools/testing/selftests/powerpc/switch_endian/Makefile b/tools/testing/selftests/powerpc/switch_endian/Makefile
new file mode 100644
index 000000000000..081473db22b7
--- /dev/null
+++ b/tools/testing/selftests/powerpc/switch_endian/Makefile
@@ -0,0 +1,24 @@
1CC := $(CROSS_COMPILE)gcc
2PROGS := switch_endian_test
3
4ASFLAGS += -O2 -Wall -g -nostdlib -m64
5
6all: $(PROGS)
7
8switch_endian_test: check-reversed.S
9
10check-reversed.o: check.o
11 $(CROSS_COMPILE)objcopy -j .text --reverse-bytes=4 -O binary $< $@
12
13check-reversed.S: check-reversed.o
14 hexdump -v -e '/1 ".byte 0x%02X\n"' $< > $@
15
16run_tests: all
17 @-for PROG in $(PROGS); do \
18 ./$$PROG; \
19 done;
20
21clean:
22 rm -f $(PROGS) *.o check-reversed.S
23
24.PHONY: all run_tests clean
diff --git a/tools/testing/selftests/powerpc/switch_endian/check.S b/tools/testing/selftests/powerpc/switch_endian/check.S
new file mode 100644
index 000000000000..e2484d2c24f4
--- /dev/null
+++ b/tools/testing/selftests/powerpc/switch_endian/check.S
@@ -0,0 +1,100 @@
1#include "common.h"
2
3/*
4 * Checks that registers contain what we expect, ie. they were not clobbered by
5 * the syscall.
6 *
7 * r15: pattern to check registers against.
8 *
9 * At the end r3 == 0 if everything's OK.
10 */
11 nop # guaranteed to be illegal in reverse-endian
12 mr r9,r15
13 cmpd r9,r3 # check r3
14 bne 1f
15 addi r9,r15,4 # check r4
16 cmpd r9,r4
17 bne 1f
18 lis r9,0x00FF # check CR
19 ori r9,r9,0xF000
20 mfcr r10
21 and r10,r10,r9
22 cmpw r9,r10
23 addi r9,r15,34
24 bne 1f
25 addi r9,r15,32 # check LR
26 mflr r10
27 cmpd r9,r10
28 bne 1f
29 addi r9,r15,5 # check r5
30 cmpd r9,r5
31 bne 1f
32 addi r9,r15,6 # check r6
33 cmpd r9,r6
34 bne 1f
35 addi r9,r15,7 # check r7
36 cmpd r9,r7
37 bne 1f
38 addi r9,r15,8 # check r8
39 cmpd r9,r8
40 bne 1f
41 addi r9,r15,13 # check r13
42 cmpd r9,r13
43 bne 1f
44 addi r9,r15,14 # check r14
45 cmpd r9,r14
46 bne 1f
47 addi r9,r15,16 # check r16
48 cmpd r9,r16
49 bne 1f
50 addi r9,r15,17 # check r17
51 cmpd r9,r17
52 bne 1f
53 addi r9,r15,18 # check r18
54 cmpd r9,r18
55 bne 1f
56 addi r9,r15,19 # check r19
57 cmpd r9,r19
58 bne 1f
59 addi r9,r15,20 # check r20
60 cmpd r9,r20
61 bne 1f
62 addi r9,r15,21 # check r21
63 cmpd r9,r21
64 bne 1f
65 addi r9,r15,22 # check r22
66 cmpd r9,r22
67 bne 1f
68 addi r9,r15,23 # check r23
69 cmpd r9,r23
70 bne 1f
71 addi r9,r15,24 # check r24
72 cmpd r9,r24
73 bne 1f
74 addi r9,r15,25 # check r25
75 cmpd r9,r25
76 bne 1f
77 addi r9,r15,26 # check r26
78 cmpd r9,r26
79 bne 1f
80 addi r9,r15,27 # check r27
81 cmpd r9,r27
82 bne 1f
83 addi r9,r15,28 # check r28
84 cmpd r9,r28
85 bne 1f
86 addi r9,r15,29 # check r29
87 cmpd r9,r29
88 bne 1f
89 addi r9,r15,30 # check r30
90 cmpd r9,r30
91 bne 1f
92 addi r9,r15,31 # check r31
93 cmpd r9,r31
94 bne 1f
95 b 2f
961: mr r3, r9
97 li r0, __NR_exit
98 sc
992: li r0, __NR_switch_endian
100 nop
diff --git a/tools/testing/selftests/powerpc/switch_endian/common.h b/tools/testing/selftests/powerpc/switch_endian/common.h
new file mode 100644
index 000000000000..69e399698c64
--- /dev/null
+++ b/tools/testing/selftests/powerpc/switch_endian/common.h
@@ -0,0 +1,6 @@
1#include <ppc-asm.h>
2#include <asm/unistd.h>
3
4#ifndef __NR_switch_endian
5#define __NR_switch_endian 363
6#endif
diff --git a/tools/testing/selftests/powerpc/switch_endian/switch_endian_test.S b/tools/testing/selftests/powerpc/switch_endian/switch_endian_test.S
new file mode 100644
index 000000000000..ef7c971abb67
--- /dev/null
+++ b/tools/testing/selftests/powerpc/switch_endian/switch_endian_test.S
@@ -0,0 +1,81 @@
1#include "common.h"
2
3 .data
4 .balign 8
5message:
6 .ascii "success: switch_endian_test\n\0"
7
8 .section ".toc"
9 .balign 8
10pattern:
11 .llong 0x5555AAAA5555AAAA
12
13 .text
14FUNC_START(_start)
15 /* Load the pattern */
16 ld r15, pattern@TOC(%r2)
17
18 /* Setup CR, only CR2-CR4 are maintained */
19 lis r3, 0x00FF
20 ori r3, r3, 0xF000
21 mtcr r3
22
23 /* Load the pattern slightly modified into the registers */
24 mr r3, r15
25 addi r4, r15, 4
26
27 addi r5, r15, 32
28 mtlr r5
29
30 addi r5, r15, 5
31 addi r6, r15, 6
32 addi r7, r15, 7
33 addi r8, r15, 8
34
35 /* r9 - r12 are clobbered */
36
37 addi r13, r15, 13
38 addi r14, r15, 14
39
40 /* Skip r15 we're using it */
41
42 addi r16, r15, 16
43 addi r17, r15, 17
44 addi r18, r15, 18
45 addi r19, r15, 19
46 addi r20, r15, 20
47 addi r21, r15, 21
48 addi r22, r15, 22
49 addi r23, r15, 23
50 addi r24, r15, 24
51 addi r25, r15, 25
52 addi r26, r15, 26
53 addi r27, r15, 27
54 addi r28, r15, 28
55 addi r29, r15, 29
56 addi r30, r15, 30
57 addi r31, r15, 31
58
59 /*
60 * Call the syscall to switch endian.
61 * It clobbers r9-r12, XER, CTR and CR0-1,5-7.
62 */
63 li r0, __NR_switch_endian
64 sc
65
66#include "check-reversed.S"
67
68 /* Flip back, r0 already has the switch syscall number */
69 .long 0x02000044 /* sc */
70
71#include "check.S"
72
73 li r0, __NR_write
74 li r3, 1 /* stdout */
75 ld r4, message@got(%r2)
76 li r5, 28 /* strlen(message3) */
77 sc
78 li r0, __NR_exit
79 li r3, 0
80 sc
81 b .
diff --git a/tools/testing/selftests/powerpc/tm/.gitignore b/tools/testing/selftests/powerpc/tm/.gitignore
index 33d02cc54a3e..2699635d2cd9 100644
--- a/tools/testing/selftests/powerpc/tm/.gitignore
+++ b/tools/testing/selftests/powerpc/tm/.gitignore
@@ -1 +1,2 @@
1tm-resched-dscr 1tm-resched-dscr
2tm-syscall
diff --git a/tools/testing/selftests/powerpc/tm/Makefile b/tools/testing/selftests/powerpc/tm/Makefile
index 34f2ec634b40..1b616fa79e93 100644
--- a/tools/testing/selftests/powerpc/tm/Makefile
+++ b/tools/testing/selftests/powerpc/tm/Makefile
@@ -1,9 +1,12 @@
1TEST_PROGS := tm-resched-dscr 1TEST_PROGS := tm-resched-dscr tm-syscall
2 2
3all: $(TEST_PROGS) 3all: $(TEST_PROGS)
4 4
5$(TEST_PROGS): ../harness.c 5$(TEST_PROGS): ../harness.c
6 6
7tm-syscall: tm-syscall-asm.S
8tm-syscall: CFLAGS += -mhtm
9
7include ../../lib.mk 10include ../../lib.mk
8 11
9clean: 12clean:
diff --git a/tools/testing/selftests/powerpc/tm/tm-syscall-asm.S b/tools/testing/selftests/powerpc/tm/tm-syscall-asm.S
new file mode 100644
index 000000000000..431f61ae2368
--- /dev/null
+++ b/tools/testing/selftests/powerpc/tm/tm-syscall-asm.S
@@ -0,0 +1,27 @@
1#include <ppc-asm.h>
2#include <asm/unistd.h>
3
4 .text
5FUNC_START(getppid_tm_active)
6 tbegin.
7 beq 1f
8 li r0, __NR_getppid
9 sc
10 tend.
11 blr
121:
13 li r3, -1
14 blr
15
16FUNC_START(getppid_tm_suspended)
17 tbegin.
18 beq 1f
19 li r0, __NR_getppid
20 tsuspend.
21 sc
22 tresume.
23 tend.
24 blr
251:
26 li r3, -1
27 blr
diff --git a/tools/testing/selftests/powerpc/tm/tm-syscall.c b/tools/testing/selftests/powerpc/tm/tm-syscall.c
new file mode 100644
index 000000000000..3ed8d4b252fa
--- /dev/null
+++ b/tools/testing/selftests/powerpc/tm/tm-syscall.c
@@ -0,0 +1,121 @@
1/*
2 * Copyright 2015, Sam Bobroff, IBM Corp.
3 * Licensed under GPLv2.
4 *
5 * Test the kernel's system call code to ensure that a system call
6 * made from within an active HTM transaction is aborted with the
7 * correct failure code.
8 * Conversely, ensure that a system call made from within a
9 * suspended transaction can succeed.
10 */
11
12#include <stdio.h>
13#include <unistd.h>
14#include <sys/syscall.h>
15#include <asm/tm.h>
16#include <asm/cputable.h>
17#include <linux/auxvec.h>
18#include <sys/time.h>
19#include <stdlib.h>
20
21#include "utils.h"
22
23extern int getppid_tm_active(void);
24extern int getppid_tm_suspended(void);
25
26unsigned retries = 0;
27
28#define TEST_DURATION 10 /* seconds */
29#define TM_RETRIES 100
30
31long failure_code(void)
32{
33 return __builtin_get_texasru() >> 24;
34}
35
36bool failure_is_persistent(void)
37{
38 return (failure_code() & TM_CAUSE_PERSISTENT) == TM_CAUSE_PERSISTENT;
39}
40
41bool failure_is_syscall(void)
42{
43 return (failure_code() & TM_CAUSE_SYSCALL) == TM_CAUSE_SYSCALL;
44}
45
46pid_t getppid_tm(bool suspend)
47{
48 int i;
49 pid_t pid;
50
51 for (i = 0; i < TM_RETRIES; i++) {
52 if (suspend)
53 pid = getppid_tm_suspended();
54 else
55 pid = getppid_tm_active();
56
57 if (pid >= 0)
58 return pid;
59
60 if (failure_is_persistent()) {
61 if (failure_is_syscall())
62 return -1;
63
64 printf("Unexpected persistent transaction failure.\n");
65 printf("TEXASR 0x%016lx, TFIAR 0x%016lx.\n",
66 __builtin_get_texasr(), __builtin_get_tfiar());
67 exit(-1);
68 }
69
70 retries++;
71 }
72
73 printf("Exceeded limit of %d temporary transaction failures.\n", TM_RETRIES);
74 printf("TEXASR 0x%016lx, TFIAR 0x%016lx.\n",
75 __builtin_get_texasr(), __builtin_get_tfiar());
76
77 exit(-1);
78}
79
80int tm_syscall(void)
81{
82 unsigned count = 0;
83 struct timeval end, now;
84
85 SKIP_IF(!((long)get_auxv_entry(AT_HWCAP2) & PPC_FEATURE2_HTM));
86 setbuf(stdout, NULL);
87
88 printf("Testing transactional syscalls for %d seconds...\n", TEST_DURATION);
89
90 gettimeofday(&end, NULL);
91 now.tv_sec = TEST_DURATION;
92 now.tv_usec = 0;
93 timeradd(&end, &now, &end);
94
95 for (count = 0; timercmp(&now, &end, <); count++) {
96 /*
97 * Test a syscall within a suspended transaction and verify
98 * that it succeeds.
99 */
100 FAIL_IF(getppid_tm(true) == -1); /* Should succeed. */
101
102 /*
103 * Test a syscall within an active transaction and verify that
104 * it fails with the correct failure code.
105 */
106 FAIL_IF(getppid_tm(false) != -1); /* Should fail... */
107 FAIL_IF(!failure_is_persistent()); /* ...persistently... */
108 FAIL_IF(!failure_is_syscall()); /* ...with code syscall. */
109 gettimeofday(&now, 0);
110 }
111
112 printf("%d active and suspended transactions behaved correctly.\n", count);
113 printf("(There were %d transaction retries.)\n", retries);
114
115 return 0;
116}
117
118int main(void)
119{
120 return test_harness(tm_syscall, "tm_syscall");
121}
diff --git a/tools/testing/selftests/powerpc/utils.h b/tools/testing/selftests/powerpc/utils.h
index a93777ae0684..b7d41086bb0a 100644
--- a/tools/testing/selftests/powerpc/utils.h
+++ b/tools/testing/selftests/powerpc/utils.h
@@ -15,11 +15,12 @@ typedef signed long long s64;
15 15
16/* Just for familiarity */ 16/* Just for familiarity */
17typedef uint32_t u32; 17typedef uint32_t u32;
18typedef uint16_t u16;
18typedef uint8_t u8; 19typedef uint8_t u8;
19 20
20 21
21int test_harness(int (test_function)(void), char *name); 22int test_harness(int (test_function)(void), char *name);
22 23extern void *get_auxv_entry(int type);
23 24
24/* Yes, this is evil */ 25/* Yes, this is evil */
25#define FAIL_IF(x) \ 26#define FAIL_IF(x) \
diff --git a/tools/testing/selftests/powerpc/vphn/.gitignore b/tools/testing/selftests/powerpc/vphn/.gitignore
new file mode 100644
index 000000000000..7c04395010cb
--- /dev/null
+++ b/tools/testing/selftests/powerpc/vphn/.gitignore
@@ -0,0 +1 @@
test-vphn
diff --git a/tools/testing/selftests/powerpc/vphn/Makefile b/tools/testing/selftests/powerpc/vphn/Makefile
new file mode 100644
index 000000000000..e539f775fd8f
--- /dev/null
+++ b/tools/testing/selftests/powerpc/vphn/Makefile
@@ -0,0 +1,15 @@
1PROG := test-vphn
2
3CFLAGS += -m64
4
5all: $(PROG)
6
7$(PROG): ../harness.c
8
9run_tests: all
10 ./$(PROG)
11
12clean:
13 rm -f $(PROG)
14
15.PHONY: all run_tests clean
diff --git a/tools/testing/selftests/powerpc/vphn/test-vphn.c b/tools/testing/selftests/powerpc/vphn/test-vphn.c
new file mode 100644
index 000000000000..5742f6876b25
--- /dev/null
+++ b/tools/testing/selftests/powerpc/vphn/test-vphn.c
@@ -0,0 +1,410 @@
1#include <stdio.h>
2#include <byteswap.h>
3#include "utils.h"
4#include "subunit.h"
5
6#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
7#define cpu_to_be32(x) bswap_32(x)
8#define be32_to_cpu(x) bswap_32(x)
9#define be16_to_cpup(x) bswap_16(*x)
10#define cpu_to_be64(x) bswap_64(x)
11#else
12#define cpu_to_be32(x) (x)
13#define be32_to_cpu(x) (x)
14#define be16_to_cpup(x) (*x)
15#define cpu_to_be64(x) (x)
16#endif
17
18#include "vphn.c"
19
20static struct test {
21 char *descr;
22 long input[VPHN_REGISTER_COUNT];
23 u32 expected[VPHN_ASSOC_BUFSIZE];
24} all_tests[] = {
25 {
26 "vphn: no data",
27 {
28 0xffffffffffffffff,
29 0xffffffffffffffff,
30 0xffffffffffffffff,
31 0xffffffffffffffff,
32 0xffffffffffffffff,
33 0xffffffffffffffff,
34 },
35 {
36 0x00000000
37 }
38 },
39 {
40 "vphn: 1 x 16-bit value",
41 {
42 0x8001ffffffffffff,
43 0xffffffffffffffff,
44 0xffffffffffffffff,
45 0xffffffffffffffff,
46 0xffffffffffffffff,
47 0xffffffffffffffff,
48 },
49 {
50 0x00000001,
51 0x00000001
52 }
53 },
54 {
55 "vphn: 2 x 16-bit values",
56 {
57 0x80018002ffffffff,
58 0xffffffffffffffff,
59 0xffffffffffffffff,
60 0xffffffffffffffff,
61 0xffffffffffffffff,
62 0xffffffffffffffff,
63 },
64 {
65 0x00000002,
66 0x00000001,
67 0x00000002
68 }
69 },
70 {
71 "vphn: 3 x 16-bit values",
72 {
73 0x800180028003ffff,
74 0xffffffffffffffff,
75 0xffffffffffffffff,
76 0xffffffffffffffff,
77 0xffffffffffffffff,
78 0xffffffffffffffff,
79 },
80 {
81 0x00000003,
82 0x00000001,
83 0x00000002,
84 0x00000003
85 }
86 },
87 {
88 "vphn: 4 x 16-bit values",
89 {
90 0x8001800280038004,
91 0xffffffffffffffff,
92 0xffffffffffffffff,
93 0xffffffffffffffff,
94 0xffffffffffffffff,
95 0xffffffffffffffff,
96 },
97 {
98 0x00000004,
99 0x00000001,
100 0x00000002,
101 0x00000003,
102 0x00000004
103 }
104 },
105 {
106 /* Parsing the next 16-bit value out of the next 64-bit input
107 * value.
108 */
109 "vphn: 5 x 16-bit values",
110 {
111 0x8001800280038004,
112 0x8005ffffffffffff,
113 0xffffffffffffffff,
114 0xffffffffffffffff,
115 0xffffffffffffffff,
116 0xffffffffffffffff,
117 },
118 {
119 0x00000005,
120 0x00000001,
121 0x00000002,
122 0x00000003,
123 0x00000004,
124 0x00000005
125 }
126 },
127 {
128 /* Parse at most 6 x 64-bit input values */
129 "vphn: 24 x 16-bit values",
130 {
131 0x8001800280038004,
132 0x8005800680078008,
133 0x8009800a800b800c,
134 0x800d800e800f8010,
135 0x8011801280138014,
136 0x8015801680178018
137 },
138 {
139 0x00000018,
140 0x00000001,
141 0x00000002,
142 0x00000003,
143 0x00000004,
144 0x00000005,
145 0x00000006,
146 0x00000007,
147 0x00000008,
148 0x00000009,
149 0x0000000a,
150 0x0000000b,
151 0x0000000c,
152 0x0000000d,
153 0x0000000e,
154 0x0000000f,
155 0x00000010,
156 0x00000011,
157 0x00000012,
158 0x00000013,
159 0x00000014,
160 0x00000015,
161 0x00000016,
162 0x00000017,
163 0x00000018
164 }
165 },
166 {
167 "vphn: 1 x 32-bit value",
168 {
169 0x00000001ffffffff,
170 0xffffffffffffffff,
171 0xffffffffffffffff,
172 0xffffffffffffffff,
173 0xffffffffffffffff,
174 0xffffffffffffffff
175 },
176 {
177 0x00000001,
178 0x00000001
179 }
180 },
181 {
182 "vphn: 2 x 32-bit values",
183 {
184 0x0000000100000002,
185 0xffffffffffffffff,
186 0xffffffffffffffff,
187 0xffffffffffffffff,
188 0xffffffffffffffff,
189 0xffffffffffffffff
190 },
191 {
192 0x00000002,
193 0x00000001,
194 0x00000002
195 }
196 },
197 {
198 /* Parsing the next 32-bit value out of the next 64-bit input
199 * value.
200 */
201 "vphn: 3 x 32-bit values",
202 {
203 0x0000000100000002,
204 0x00000003ffffffff,
205 0xffffffffffffffff,
206 0xffffffffffffffff,
207 0xffffffffffffffff,
208 0xffffffffffffffff
209 },
210 {
211 0x00000003,
212 0x00000001,
213 0x00000002,
214 0x00000003
215 }
216 },
217 {
218 /* Parse at most 6 x 64-bit input values */
219 "vphn: 12 x 32-bit values",
220 {
221 0x0000000100000002,
222 0x0000000300000004,
223 0x0000000500000006,
224 0x0000000700000008,
225 0x000000090000000a,
226 0x0000000b0000000c
227 },
228 {
229 0x0000000c,
230 0x00000001,
231 0x00000002,
232 0x00000003,
233 0x00000004,
234 0x00000005,
235 0x00000006,
236 0x00000007,
237 0x00000008,
238 0x00000009,
239 0x0000000a,
240 0x0000000b,
241 0x0000000c
242 }
243 },
244 {
245 "vphn: 16-bit value followed by 32-bit value",
246 {
247 0x800100000002ffff,
248 0xffffffffffffffff,
249 0xffffffffffffffff,
250 0xffffffffffffffff,
251 0xffffffffffffffff,
252 0xffffffffffffffff
253 },
254 {
255 0x00000002,
256 0x00000001,
257 0x00000002
258 }
259 },
260 {
261 "vphn: 32-bit value followed by 16-bit value",
262 {
263 0x000000018002ffff,
264 0xffffffffffffffff,
265 0xffffffffffffffff,
266 0xffffffffffffffff,
267 0xffffffffffffffff,
268 0xffffffffffffffff
269 },
270 {
271 0x00000002,
272 0x00000001,
273 0x00000002
274 }
275 },
276 {
277 /* Parse a 32-bit value split accross two consecutives 64-bit
278 * input values.
279 */
280 "vphn: 16-bit value followed by 2 x 32-bit values",
281 {
282 0x8001000000020000,
283 0x0003ffffffffffff,
284 0xffffffffffffffff,
285 0xffffffffffffffff,
286 0xffffffffffffffff,
287 0xffffffffffffffff
288 },
289 {
290 0x00000003,
291 0x00000001,
292 0x00000002,
293 0x00000003,
294 0x00000004,
295 0x00000005
296 }
297 },
298 {
299 /* The lower bits in 0x0001ffff don't get mixed up with the
300 * 0xffff terminator.
301 */
302 "vphn: 32-bit value has all ones in 16 lower bits",
303 {
304 0x0001ffff80028003,
305 0xffffffffffffffff,
306 0xffffffffffffffff,
307 0xffffffffffffffff,
308 0xffffffffffffffff,
309 0xffffffffffffffff
310 },
311 {
312 0x00000003,
313 0x0001ffff,
314 0x00000002,
315 0x00000003
316 }
317 },
318 {
319 /* The following input doesn't follow the specification.
320 */
321 "vphn: last 32-bit value is truncated",
322 {
323 0x0000000100000002,
324 0x0000000300000004,
325 0x0000000500000006,
326 0x0000000700000008,
327 0x000000090000000a,
328 0x0000000b800c2bad
329 },
330 {
331 0x0000000c,
332 0x00000001,
333 0x00000002,
334 0x00000003,
335 0x00000004,
336 0x00000005,
337 0x00000006,
338 0x00000007,
339 0x00000008,
340 0x00000009,
341 0x0000000a,
342 0x0000000b,
343 0x0000000c
344 }
345 },
346 {
347 "vphn: garbage after terminator",
348 {
349 0xffff2bad2bad2bad,
350 0x2bad2bad2bad2bad,
351 0x2bad2bad2bad2bad,
352 0x2bad2bad2bad2bad,
353 0x2bad2bad2bad2bad,
354 0x2bad2bad2bad2bad
355 },
356 {
357 0x00000000
358 }
359 },
360 {
361 NULL
362 }
363};
364
365static int test_one(struct test *test)
366{
367 __be32 output[VPHN_ASSOC_BUFSIZE] = { 0 };
368 int i, len;
369
370 vphn_unpack_associativity(test->input, output);
371
372 len = be32_to_cpu(output[0]);
373 if (len != test->expected[0]) {
374 printf("expected %d elements, got %d\n", test->expected[0],
375 len);
376 return 1;
377 }
378
379 for (i = 1; i < len; i++) {
380 u32 val = be32_to_cpu(output[i]);
381 if (val != test->expected[i]) {
382 printf("element #%d is 0x%x, should be 0x%x\n", i, val,
383 test->expected[i]);
384 return 1;
385 }
386 }
387
388 return 0;
389}
390
391static int test_vphn(void)
392{
393 static struct test *test;
394
395 for (test = all_tests; test->descr; test++) {
396 int ret;
397
398 ret = test_one(test);
399 test_finish(test->descr, ret);
400 if (ret)
401 return ret;
402 }
403
404 return 0;
405}
406
407int main(int argc, char **argv)
408{
409 return test_harness(test_vphn, "test-vphn");
410}
diff --git a/tools/testing/selftests/powerpc/vphn/vphn.c b/tools/testing/selftests/powerpc/vphn/vphn.c
new file mode 120000
index 000000000000..186b906e66d5
--- /dev/null
+++ b/tools/testing/selftests/powerpc/vphn/vphn.c
@@ -0,0 +1 @@
../../../../../arch/powerpc/mm/vphn.c \ No newline at end of file
diff --git a/tools/testing/selftests/powerpc/vphn/vphn.h b/tools/testing/selftests/powerpc/vphn/vphn.h
new file mode 120000
index 000000000000..7131efe38c65
--- /dev/null
+++ b/tools/testing/selftests/powerpc/vphn/vphn.h
@@ -0,0 +1 @@
../../../../../arch/powerpc/mm/vphn.h \ No newline at end of file