Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Michael Ellerman and committed by
Benjamin Herrenschmidt
22d651dc 55672ecf

+220 -1
+2
arch/powerpc/lib/memcpy_64.S
··· 14 14 BEGIN_FTR_SECTION 15 15 std r3,48(r1) /* save destination pointer for return value */ 16 16 FTR_SECTION_ELSE 17 + #ifndef SELFTEST 17 18 b memcpy_power7 19 + #endif 18 20 ALT_FTR_SECTION_END_IFCLR(CPU_FTR_VMX_COPY) 19 21 PPC_MTOCRF(0x01,r5) 20 22 cmpldi cr1,r5,16
+1 -1
tools/testing/selftests/powerpc/Makefile
··· 13 13 14 14 export CC CFLAGS 15 15 16 - TARGETS = pmu 16 + TARGETS = pmu copyloops 17 17 18 18 endif 19 19
+29
tools/testing/selftests/powerpc/copyloops/Makefile
··· 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
+86
tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h
··· 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)
tools/testing/selftests/powerpc/copyloops/asm/processor.h
+99
tools/testing/selftests/powerpc/copyloops/validate.c
··· 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 + }
+3
tools/testing/selftests/powerpc/utils.h
··· 31 31 } \ 32 32 } while (0) 33 33 34 + #define _str(s) #s 35 + #define str(s) _str(s) 36 + 34 37 #endif /* _SELFTESTS_POWERPC_UTILS_H */