Skip to content

Commit

Permalink
selftests/powerpc: Import Anton's memcpy / copy_tofrom_user tests
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Michael Ellerman authored and Benjamin Herrenschmidt committed Mar 7, 2014
1 parent 55672ec commit 22d651d
Show file tree
Hide file tree
Showing 11 changed files with 224 additions and 1 deletion.
2 changes: 2 additions & 0 deletions arch/powerpc/lib/memcpy_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ _GLOBAL(memcpy)
BEGIN_FTR_SECTION
std r3,48(r1) /* save destination pointer for return value */
FTR_SECTION_ELSE
#ifndef SELFTEST
b memcpy_power7
#endif
ALT_FTR_SECTION_END_IFCLR(CPU_FTR_VMX_COPY)
PPC_MTOCRF(0x01,r5)
cmpldi cr1,r5,16
Expand Down
2 changes: 1 addition & 1 deletion tools/testing/selftests/powerpc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ CFLAGS := -Wall -O2 -flto -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CUR

export CC CFLAGS

TARGETS = pmu
TARGETS = pmu copyloops

endif

Expand Down
29 changes: 29 additions & 0 deletions tools/testing/selftests/powerpc/copyloops/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# The loops are all 64-bit code
CFLAGS += -m64
CFLAGS += -I$(CURDIR)
CFLAGS += -D SELFTEST

# Use our CFLAGS for the implicit .S rule
ASFLAGS = $(CFLAGS)

PROGS := copyuser_64 copyuser_power7 memcpy_64 memcpy_power7
EXTRA_SOURCES := validate.c ../harness.c

all: $(PROGS)

copyuser_64: CPPFLAGS += -D COPY_LOOP=test___copy_tofrom_user_base
copyuser_power7: CPPFLAGS += -D COPY_LOOP=test___copy_tofrom_user_power7
memcpy_64: CPPFLAGS += -D COPY_LOOP=test_memcpy
memcpy_power7: CPPFLAGS += -D COPY_LOOP=test_memcpy_power7

$(PROGS): $(EXTRA_SOURCES)

run_tests: all
@-for PROG in $(PROGS); do \
./$$PROG; \
done;

clean:
rm -f $(PROGS) *.o

.PHONY: all run_tests clean
86 changes: 86 additions & 0 deletions tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#include <ppc-asm.h>

#define CONFIG_ALTIVEC

#define r1 1

#define vr0 0
#define vr1 1
#define vr2 2
#define vr3 3
#define vr4 4
#define vr5 5
#define vr6 6
#define vr7 7
#define vr8 8
#define vr9 9
#define vr10 10
#define vr11 11
#define vr12 12
#define vr13 13
#define vr14 14
#define vr15 15
#define vr16 16
#define vr17 17
#define vr18 18
#define vr19 19
#define vr20 20
#define vr21 21
#define vr22 22
#define vr23 23
#define vr24 24
#define vr25 25
#define vr26 26
#define vr27 27
#define vr28 28
#define vr29 29
#define vr30 30
#define vr31 31

#define R14 r14
#define R15 r15
#define R16 r16
#define R17 r17
#define R18 r18
#define R19 r19
#define R20 r20
#define R21 r21
#define R22 r22

#define STACKFRAMESIZE 256
#define STK_PARAM(i) (48 + ((i)-3)*8)
#define STK_REG(i) (112 + ((i)-14)*8)

#define _GLOBAL(A) FUNC_START(test_ ## A)

#define PPC_MTOCRF(A, B) mtocrf A, B

FUNC_START(enter_vmx_usercopy)
li r3,1
blr

FUNC_START(exit_vmx_usercopy)
li r3,0
blr

FUNC_START(enter_vmx_copy)
li r3,1
blr

FUNC_START(exit_vmx_copy)
blr

FUNC_START(memcpy_power7)
blr

FUNC_START(__copy_tofrom_user_power7)
blr

FUNC_START(__copy_tofrom_user_base)
blr

#define BEGIN_FTR_SECTION
#define FTR_SECTION_ELSE
#define ALT_FTR_SECTION_END_IFCLR(x)
#define ALT_FTR_SECTION_END(x, y)
#define END_FTR_SECTION_IFCLR(x)
Empty file.
1 change: 1 addition & 0 deletions tools/testing/selftests/powerpc/copyloops/copyuser_64.S
1 change: 1 addition & 0 deletions tools/testing/selftests/powerpc/copyloops/memcpy_64.S
1 change: 1 addition & 0 deletions tools/testing/selftests/powerpc/copyloops/memcpy_power7.S
99 changes: 99 additions & 0 deletions tools/testing/selftests/powerpc/copyloops/validate.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>

#include "../utils.h"

#define MAX_LEN 8192
#define MAX_OFFSET 16
#define MIN_REDZONE 128
#define BUFLEN (MAX_LEN+MAX_OFFSET+2*MIN_REDZONE)
#define POISON 0xa5

unsigned long COPY_LOOP(void *to, const void *from, unsigned long size);

static void do_one(char *src, char *dst, unsigned long src_off,
unsigned long dst_off, unsigned long len, void *redzone,
void *fill)
{
char *srcp, *dstp;
unsigned long ret;
unsigned long i;

srcp = src + MIN_REDZONE + src_off;
dstp = dst + MIN_REDZONE + dst_off;

memset(src, POISON, BUFLEN);
memset(dst, POISON, BUFLEN);
memcpy(srcp, fill, len);

ret = COPY_LOOP(dstp, srcp, len);
if (ret && ret != (unsigned long)dstp) {
printf("(%p,%p,%ld) returned %ld\n", dstp, srcp, len, ret);
abort();
}

if (memcmp(dstp, srcp, len)) {
printf("(%p,%p,%ld) miscompare\n", dstp, srcp, len);
printf("src: ");
for (i = 0; i < len; i++)
printf("%02x ", srcp[i]);
printf("\ndst: ");
for (i = 0; i < len; i++)
printf("%02x ", dstp[i]);
printf("\n");
abort();
}

if (memcmp(dst, redzone, dstp - dst)) {
printf("(%p,%p,%ld) redzone before corrupted\n",
dstp, srcp, len);
abort();
}

if (memcmp(dstp+len, redzone, dst+BUFLEN-(dstp+len))) {
printf("(%p,%p,%ld) redzone after corrupted\n",
dstp, srcp, len);
abort();
}
}

int test_copy_loop(void)
{
char *src, *dst, *redzone, *fill;
unsigned long len, src_off, dst_off;
unsigned long i;

src = memalign(BUFLEN, BUFLEN);
dst = memalign(BUFLEN, BUFLEN);
redzone = malloc(BUFLEN);
fill = malloc(BUFLEN);

if (!src || !dst || !redzone || !fill) {
fprintf(stderr, "malloc failed\n");
exit(1);
}

memset(redzone, POISON, BUFLEN);

/* Fill with sequential bytes */
for (i = 0; i < BUFLEN; i++)
fill[i] = i & 0xff;

for (len = 1; len < MAX_LEN; len++) {
for (src_off = 0; src_off < MAX_OFFSET; src_off++) {
for (dst_off = 0; dst_off < MAX_OFFSET; dst_off++) {
do_one(src, dst, src_off, dst_off, len,
redzone, fill);
}
}
}

return 0;
}

int main(void)
{
return test_harness(test_copy_loop, str(COPY_LOOP));
}
3 changes: 3 additions & 0 deletions tools/testing/selftests/powerpc/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,7 @@ do { \
} \
} while (0)

#define _str(s) #s
#define str(s) _str(s)

#endif /* _SELFTESTS_POWERPC_UTILS_H */

0 comments on commit 22d651d

Please sign in to comment.