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/testing | |
| 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/testing')
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 */ |
