diff options
author | Michael Ellerman <mpe@ellerman.id.au> | 2014-01-20 23:22:17 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2014-03-06 23:53:12 -0500 |
commit | 22d651dcef536c75f75537290bf3da5038e68b6b (patch) | |
tree | f235898edcb89a9fe9dbf2f9f76b79f78596b16e /tools | |
parent | 55672ecfa21f23616541c50e0e687f14f9ecf165 (diff) |
selftests/powerpc: Import Anton's memcpy / copy_tofrom_user tests
Turn Anton's memcpy / copy_tofrom_user test into something that can
live in tools/testing/selftests.
It requires one turd in arch/powerpc/lib/memcpy_64.S, but it's pretty
harmless IMHO.
We are sailing very close to the wind with the feature macros. We define
them to nothing, which currently means we get a few extra nops and
include the unaligned calls.
Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'tools')
10 files changed, 222 insertions, 1 deletions
diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile index bd24ae5aaeab..316194f26ff4 100644 --- a/tools/testing/selftests/powerpc/Makefile +++ b/tools/testing/selftests/powerpc/Makefile | |||
@@ -13,7 +13,7 @@ CFLAGS := -Wall -O2 -flto -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CUR | |||
13 | 13 | ||
14 | export CC CFLAGS | 14 | export CC CFLAGS |
15 | 15 | ||
16 | TARGETS = pmu | 16 | TARGETS = pmu copyloops |
17 | 17 | ||
18 | endif | 18 | endif |
19 | 19 | ||
diff --git a/tools/testing/selftests/powerpc/copyloops/Makefile b/tools/testing/selftests/powerpc/copyloops/Makefile new file mode 100644 index 000000000000..6f2d3be227f9 --- /dev/null +++ b/tools/testing/selftests/powerpc/copyloops/Makefile | |||
@@ -0,0 +1,29 @@ | |||
1 | # The loops are all 64-bit code | ||
2 | CFLAGS += -m64 | ||
3 | CFLAGS += -I$(CURDIR) | ||
4 | CFLAGS += -D SELFTEST | ||
5 | |||
6 | # Use our CFLAGS for the implicit .S rule | ||
7 | ASFLAGS = $(CFLAGS) | ||
8 | |||
9 | PROGS := copyuser_64 copyuser_power7 memcpy_64 memcpy_power7 | ||
10 | EXTRA_SOURCES := validate.c ../harness.c | ||
11 | |||
12 | all: $(PROGS) | ||
13 | |||
14 | copyuser_64: CPPFLAGS += -D COPY_LOOP=test___copy_tofrom_user_base | ||
15 | copyuser_power7: CPPFLAGS += -D COPY_LOOP=test___copy_tofrom_user_power7 | ||
16 | memcpy_64: CPPFLAGS += -D COPY_LOOP=test_memcpy | ||
17 | memcpy_power7: CPPFLAGS += -D COPY_LOOP=test_memcpy_power7 | ||
18 | |||
19 | $(PROGS): $(EXTRA_SOURCES) | ||
20 | |||
21 | run_tests: all | ||
22 | @-for PROG in $(PROGS); do \ | ||
23 | ./$$PROG; \ | ||
24 | done; | ||
25 | |||
26 | clean: | ||
27 | rm -f $(PROGS) *.o | ||
28 | |||
29 | .PHONY: all run_tests clean | ||
diff --git a/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h b/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h new file mode 100644 index 000000000000..ccd9c84c4e3f --- /dev/null +++ b/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h | |||
@@ -0,0 +1,86 @@ | |||
1 | #include <ppc-asm.h> | ||
2 | |||
3 | #define CONFIG_ALTIVEC | ||
4 | |||
5 | #define r1 1 | ||
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 | ||
41 | #define R15 r15 | ||
42 | #define R16 r16 | ||
43 | #define R17 r17 | ||
44 | #define R18 r18 | ||
45 | #define R19 r19 | ||
46 | #define R20 r20 | ||
47 | #define R21 r21 | ||
48 | #define R22 r22 | ||
49 | |||
50 | #define STACKFRAMESIZE 256 | ||
51 | #define STK_PARAM(i) (48 + ((i)-3)*8) | ||
52 | #define STK_REG(i) (112 + ((i)-14)*8) | ||
53 | |||
54 | #define _GLOBAL(A) FUNC_START(test_ ## A) | ||
55 | |||
56 | #define PPC_MTOCRF(A, B) mtocrf A, B | ||
57 | |||
58 | FUNC_START(enter_vmx_usercopy) | ||
59 | li r3,1 | ||
60 | blr | ||
61 | |||
62 | FUNC_START(exit_vmx_usercopy) | ||
63 | li r3,0 | ||
64 | blr | ||
65 | |||
66 | FUNC_START(enter_vmx_copy) | ||
67 | li r3,1 | ||
68 | blr | ||
69 | |||
70 | FUNC_START(exit_vmx_copy) | ||
71 | blr | ||
72 | |||
73 | FUNC_START(memcpy_power7) | ||
74 | blr | ||
75 | |||
76 | FUNC_START(__copy_tofrom_user_power7) | ||
77 | blr | ||
78 | |||
79 | FUNC_START(__copy_tofrom_user_base) | ||
80 | blr | ||
81 | |||
82 | #define BEGIN_FTR_SECTION | ||
83 | #define FTR_SECTION_ELSE | ||
84 | #define ALT_FTR_SECTION_END_IFCLR(x) | ||
85 | #define ALT_FTR_SECTION_END(x, y) | ||
86 | #define END_FTR_SECTION_IFCLR(x) | ||
diff --git a/tools/testing/selftests/powerpc/copyloops/asm/processor.h b/tools/testing/selftests/powerpc/copyloops/asm/processor.h new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/tools/testing/selftests/powerpc/copyloops/asm/processor.h | |||
diff --git a/tools/testing/selftests/powerpc/copyloops/copyuser_64.S b/tools/testing/selftests/powerpc/copyloops/copyuser_64.S new file mode 120000 index 000000000000..f1c418a2521a --- /dev/null +++ b/tools/testing/selftests/powerpc/copyloops/copyuser_64.S | |||
@@ -0,0 +1 @@ | |||
../../../../../arch/powerpc/lib/copyuser_64.S \ No newline at end of file | |||
diff --git a/tools/testing/selftests/powerpc/copyloops/copyuser_power7.S b/tools/testing/selftests/powerpc/copyloops/copyuser_power7.S new file mode 120000 index 000000000000..478689598298 --- /dev/null +++ b/tools/testing/selftests/powerpc/copyloops/copyuser_power7.S | |||
@@ -0,0 +1 @@ | |||
../../../../../arch/powerpc/lib/copyuser_power7.S \ No newline at end of file | |||
diff --git a/tools/testing/selftests/powerpc/copyloops/memcpy_64.S b/tools/testing/selftests/powerpc/copyloops/memcpy_64.S new file mode 120000 index 000000000000..cce33fb6f9d8 --- /dev/null +++ b/tools/testing/selftests/powerpc/copyloops/memcpy_64.S | |||
@@ -0,0 +1 @@ | |||
../../../../../arch/powerpc/lib/memcpy_64.S \ No newline at end of file | |||
diff --git a/tools/testing/selftests/powerpc/copyloops/memcpy_power7.S b/tools/testing/selftests/powerpc/copyloops/memcpy_power7.S new file mode 120000 index 000000000000..0d6fbfaf3d59 --- /dev/null +++ b/tools/testing/selftests/powerpc/copyloops/memcpy_power7.S | |||
@@ -0,0 +1 @@ | |||
../../../../../arch/powerpc/lib/memcpy_power7.S \ No newline at end of file | |||
diff --git a/tools/testing/selftests/powerpc/copyloops/validate.c b/tools/testing/selftests/powerpc/copyloops/validate.c new file mode 100644 index 000000000000..1750ff57ee58 --- /dev/null +++ b/tools/testing/selftests/powerpc/copyloops/validate.c | |||
@@ -0,0 +1,99 @@ | |||
1 | #include <malloc.h> | ||
2 | #include <string.h> | ||
3 | #include <stdlib.h> | ||
4 | #include <stdbool.h> | ||
5 | |||
6 | #include "../utils.h" | ||
7 | |||
8 | #define MAX_LEN 8192 | ||
9 | #define MAX_OFFSET 16 | ||
10 | #define MIN_REDZONE 128 | ||
11 | #define BUFLEN (MAX_LEN+MAX_OFFSET+2*MIN_REDZONE) | ||
12 | #define POISON 0xa5 | ||
13 | |||
14 | unsigned long COPY_LOOP(void *to, const void *from, unsigned long size); | ||
15 | |||
16 | static void do_one(char *src, char *dst, unsigned long src_off, | ||
17 | unsigned long dst_off, unsigned long len, void *redzone, | ||
18 | void *fill) | ||
19 | { | ||
20 | char *srcp, *dstp; | ||
21 | unsigned long ret; | ||
22 | unsigned long i; | ||
23 | |||
24 | srcp = src + MIN_REDZONE + src_off; | ||
25 | dstp = dst + MIN_REDZONE + dst_off; | ||
26 | |||
27 | memset(src, POISON, BUFLEN); | ||
28 | memset(dst, POISON, BUFLEN); | ||
29 | memcpy(srcp, fill, len); | ||
30 | |||
31 | ret = COPY_LOOP(dstp, srcp, len); | ||
32 | if (ret && ret != (unsigned long)dstp) { | ||
33 | printf("(%p,%p,%ld) returned %ld\n", dstp, srcp, len, ret); | ||
34 | abort(); | ||
35 | } | ||
36 | |||
37 | if (memcmp(dstp, srcp, len)) { | ||
38 | printf("(%p,%p,%ld) miscompare\n", dstp, srcp, len); | ||
39 | printf("src: "); | ||
40 | for (i = 0; i < len; i++) | ||
41 | printf("%02x ", srcp[i]); | ||
42 | printf("\ndst: "); | ||
43 | for (i = 0; i < len; i++) | ||
44 | printf("%02x ", dstp[i]); | ||
45 | printf("\n"); | ||
46 | abort(); | ||
47 | } | ||
48 | |||
49 | if (memcmp(dst, redzone, dstp - dst)) { | ||
50 | printf("(%p,%p,%ld) redzone before corrupted\n", | ||
51 | dstp, srcp, len); | ||
52 | abort(); | ||
53 | } | ||
54 | |||
55 | if (memcmp(dstp+len, redzone, dst+BUFLEN-(dstp+len))) { | ||
56 | printf("(%p,%p,%ld) redzone after corrupted\n", | ||
57 | dstp, srcp, len); | ||
58 | abort(); | ||
59 | } | ||
60 | } | ||
61 | |||
62 | int test_copy_loop(void) | ||
63 | { | ||
64 | char *src, *dst, *redzone, *fill; | ||
65 | unsigned long len, src_off, dst_off; | ||
66 | unsigned long i; | ||
67 | |||
68 | src = memalign(BUFLEN, BUFLEN); | ||
69 | dst = memalign(BUFLEN, BUFLEN); | ||
70 | redzone = malloc(BUFLEN); | ||
71 | fill = malloc(BUFLEN); | ||
72 | |||
73 | if (!src || !dst || !redzone || !fill) { | ||
74 | fprintf(stderr, "malloc failed\n"); | ||
75 | exit(1); | ||
76 | } | ||
77 | |||
78 | memset(redzone, POISON, BUFLEN); | ||
79 | |||
80 | /* Fill with sequential bytes */ | ||
81 | for (i = 0; i < BUFLEN; i++) | ||
82 | fill[i] = i & 0xff; | ||
83 | |||
84 | for (len = 1; len < MAX_LEN; len++) { | ||
85 | for (src_off = 0; src_off < MAX_OFFSET; src_off++) { | ||
86 | for (dst_off = 0; dst_off < MAX_OFFSET; dst_off++) { | ||
87 | do_one(src, dst, src_off, dst_off, len, | ||
88 | redzone, fill); | ||
89 | } | ||
90 | } | ||
91 | } | ||
92 | |||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | int main(void) | ||
97 | { | ||
98 | return test_harness(test_copy_loop, str(COPY_LOOP)); | ||
99 | } | ||
diff --git a/tools/testing/selftests/powerpc/utils.h b/tools/testing/selftests/powerpc/utils.h index 5851c4b0f553..0de064406dab 100644 --- a/tools/testing/selftests/powerpc/utils.h +++ b/tools/testing/selftests/powerpc/utils.h | |||
@@ -31,4 +31,7 @@ do { \ | |||
31 | } \ | 31 | } \ |
32 | } while (0) | 32 | } while (0) |
33 | 33 | ||
34 | #define _str(s) #s | ||
35 | #define str(s) _str(s) | ||
36 | |||
34 | #endif /* _SELFTESTS_POWERPC_UTILS_H */ | 37 | #endif /* _SELFTESTS_POWERPC_UTILS_H */ |