While debugging an issue, we wanted to check whether the arch specific
kernel memmove implementation is correct.
This selftest could help test that.

Suggested-by: Aneesh Kumar K.V <aneesh.ku...@linux.ibm.com>
Suggested-by: Vaibhav Jain <vaib...@linux.ibm.com>
Signed-off-by: Ritesh Harjani <rite...@linux.ibm.com>
---
v1 -> v2: Integrated memmove_64 test within copyloops tests
[v1]: https://patchwork.ozlabs.org/patch/1518082

 .../selftests/powerpc/copyloops/.gitignore    |  1 +
 .../selftests/powerpc/copyloops/Makefile      |  9 ++-
 .../selftests/powerpc/copyloops/asm/ppc_asm.h |  1 +
 .../selftests/powerpc/copyloops/mem_64.S      |  1 +
 .../powerpc/copyloops/memcpy_stubs.S          |  8 +++
 .../powerpc/copyloops/memmove_validate.c      | 58 +++++++++++++++++++
 6 files changed, 77 insertions(+), 1 deletion(-)
 create mode 120000 tools/testing/selftests/powerpc/copyloops/mem_64.S
 create mode 100644 tools/testing/selftests/powerpc/copyloops/memcpy_stubs.S
 create mode 100644 tools/testing/selftests/powerpc/copyloops/memmove_validate.c

diff --git a/tools/testing/selftests/powerpc/copyloops/.gitignore 
b/tools/testing/selftests/powerpc/copyloops/.gitignore
index 994b11af765c..7283e8b07b75 100644
--- a/tools/testing/selftests/powerpc/copyloops/.gitignore
+++ b/tools/testing/selftests/powerpc/copyloops/.gitignore
@@ -13,3 +13,4 @@ copyuser_64_exc_t0
 copyuser_64_exc_t1
 copyuser_64_exc_t2
 copy_mc_64
+memmove_64
diff --git a/tools/testing/selftests/powerpc/copyloops/Makefile 
b/tools/testing/selftests/powerpc/copyloops/Makefile
index 3095b1f1c02b..77594e697f2f 100644
--- a/tools/testing/selftests/powerpc/copyloops/Makefile
+++ b/tools/testing/selftests/powerpc/copyloops/Makefile
@@ -13,7 +13,8 @@ TEST_GEN_PROGS := copyuser_64_t0 copyuser_64_t1 
copyuser_64_t2 \
                copyuser_p7_t0 copyuser_p7_t1 \
                memcpy_64_t0 memcpy_64_t1 memcpy_64_t2 \
                memcpy_p7_t0 memcpy_p7_t1 copy_mc_64 \
-               copyuser_64_exc_t0 copyuser_64_exc_t1 copyuser_64_exc_t2
+               copyuser_64_exc_t0 copyuser_64_exc_t1 copyuser_64_exc_t2 \
+               memmove_64

 EXTRA_SOURCES := validate.c ../harness.c stubs.S

@@ -56,3 +57,9 @@ $(OUTPUT)/copyuser_64_exc_t%: copyuser_64.S exc_validate.c 
../harness.c \
                -D COPY_LOOP=test___copy_tofrom_user_base \
                -D SELFTEST_CASE=$(subst copyuser_64_exc_t,,$(notdir $@)) \
                -o $@ $^
+
+$(OUTPUT)/memmove_64: mem_64.S memcpy_64.S memmove_validate.c ../harness.c \
+               memcpy_stubs.S
+       $(CC) $(CPPFLAGS) $(CFLAGS) \
+               -D TEST_MEMMOVE=test_memmove \
+               -o $@ $^
diff --git a/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h 
b/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h
index 58c1cef3e399..003e1b3d9300 100644
--- a/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h
+++ b/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h
@@ -26,6 +26,7 @@
 #define _GLOBAL(A) FUNC_START(test_ ## A)
 #define _GLOBAL_TOC(A) _GLOBAL(A)
 #define _GLOBAL_TOC_KASAN(A) _GLOBAL(A)
+#define _GLOBAL_KASAN(A) _GLOBAL(A)

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

diff --git a/tools/testing/selftests/powerpc/copyloops/mem_64.S 
b/tools/testing/selftests/powerpc/copyloops/mem_64.S
new file mode 120000
index 000000000000..db254c9a5f5c
--- /dev/null
+++ b/tools/testing/selftests/powerpc/copyloops/mem_64.S
@@ -0,0 +1 @@
+../../../../../arch/powerpc/lib/mem_64.S
\ No newline at end of file
diff --git a/tools/testing/selftests/powerpc/copyloops/memcpy_stubs.S 
b/tools/testing/selftests/powerpc/copyloops/memcpy_stubs.S
new file mode 100644
index 000000000000..d9baa832fa49
--- /dev/null
+++ b/tools/testing/selftests/powerpc/copyloops/memcpy_stubs.S
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <asm/ppc_asm.h>
+
+FUNC_START(memcpy)
+       b test_memcpy
+
+FUNC_START(backwards_memcpy)
+       b test_backwards_memcpy
diff --git a/tools/testing/selftests/powerpc/copyloops/memmove_validate.c 
b/tools/testing/selftests/powerpc/copyloops/memmove_validate.c
new file mode 100644
index 000000000000..1a23218b5757
--- /dev/null
+++ b/tools/testing/selftests/powerpc/copyloops/memmove_validate.c
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <malloc.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "utils.h"
+
+void *TEST_MEMMOVE(const void *s1, const void *s2, size_t n);
+
+#define BUF_LEN 65536
+#define MAX_OFFSET 512
+
+size_t max(size_t a, size_t b)
+{
+       if (a >= b)
+               return a;
+       return b;
+}
+
+static int testcase_run(void)
+{
+       size_t i, src_off, dst_off, len;
+
+       char *usermap = memalign(BUF_LEN, BUF_LEN);
+       char *kernelmap = memalign(BUF_LEN, BUF_LEN);
+
+       assert(usermap != NULL);
+       assert(kernelmap != NULL);
+
+       memset(usermap, 0, BUF_LEN);
+       memset(kernelmap, 0, BUF_LEN);
+
+       for (i = 0; i < BUF_LEN; i++) {
+               usermap[i] = i & 0xff;
+               kernelmap[i] = i & 0xff;
+       }
+
+       for (src_off = 0; src_off < MAX_OFFSET; src_off++) {
+               for (dst_off = 0; dst_off < MAX_OFFSET; dst_off++) {
+                       for (len = 1; len < MAX_OFFSET - max(src_off, dst_off); 
len++) {
+
+                               memmove(usermap + dst_off, usermap + src_off, 
len);
+                               TEST_MEMMOVE(kernelmap + dst_off, kernelmap + 
src_off, len);
+                               if (memcmp(usermap, kernelmap, MAX_OFFSET) != 
0) {
+                                       printf("memmove failed at %ld %ld 
%ld\n",
+                                                       src_off, dst_off, len);
+                                       abort();
+                               }
+                       }
+               }
+       }
+       return 0;
+}
+
+int main(void)
+{
+       return test_harness(testcase_run, "memmove");
+}
--
2.31.1

Reply via email to