{"id":690684,"url":"http://patchwork.ozlabs.org/api/patches/690684/?format=json","web_url":"http://patchwork.ozlabs.org/project/linuxppc-dev/patch/20161103052140.GE8368@fergus.ozlabs.ibm.com/","project":{"id":2,"url":"http://patchwork.ozlabs.org/api/projects/2/?format=json","name":"Linux PPC development","link_name":"linuxppc-dev","list_id":"linuxppc-dev.lists.ozlabs.org","list_email":"linuxppc-dev@lists.ozlabs.org","web_url":"https://github.com/linuxppc/wiki/wiki","scm_url":"https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git","webscm_url":"https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/","list_archive_url":"https://lore.kernel.org/linuxppc-dev/","list_archive_url_format":"https://lore.kernel.org/linuxppc-dev/{}/","commit_url_format":"https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/commit/?id={}"},"msgid":"<20161103052140.GE8368@fergus.ozlabs.ibm.com>","list_archive_url":"https://lore.kernel.org/linuxppc-dev/20161103052140.GE8368@fergus.ozlabs.ibm.com/","date":"2016-11-03T05:21:40","name":"[3/4] selftests/powerpc/64: Test exception cases in copy_tofrom_user","commit_ref":null,"pull_url":null,"state":"superseded","archived":true,"hash":"dab31af0e62439b57e1fb4e0cf47349838385a33","submitter":{"id":67079,"url":"http://patchwork.ozlabs.org/api/people/67079/?format=json","name":"Paul Mackerras","email":"paulus@ozlabs.org"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linuxppc-dev/patch/20161103052140.GE8368@fergus.ozlabs.ibm.com/mbox/","series":[],"comments":"http://patchwork.ozlabs.org/api/patches/690684/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/690684/checks/","tags":{},"related":[],"headers":{"Return-Path":"<linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org>","X-Original-To":["patchwork-incoming@ozlabs.org","linuxppc-dev@lists.ozlabs.org"],"Delivered-To":["patchwork-incoming@ozlabs.org","linuxppc-dev@lists.ozlabs.org","linuxppc-dev@ozlabs.org"],"Received":["from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3])\n\t(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3t8YMb0FgSz9t10\n\tfor <patchwork-incoming@ozlabs.org>;\n\tThu,  3 Nov 2016 16:25:31 +1100 (AEDT)","from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3])\n\tby lists.ozlabs.org (Postfix) with ESMTP id 3t8YMZ6MRDzDvc6\n\tfor <patchwork-incoming@ozlabs.org>;\n\tThu,  3 Nov 2016 16:25:30 +1100 (AEDT)","from ozlabs.org (ozlabs.org [IPv6:2401:3900:2:1::2])\n\t(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby lists.ozlabs.org (Postfix) with ESMTPS id 3t8YK15dLTzDvQV\n\tfor <linuxppc-dev@lists.ozlabs.org>;\n\tThu,  3 Nov 2016 16:23:17 +1100 (AEDT)","by ozlabs.org (Postfix)\n\tid 3t8YK14mfwz9t2T; Thu,  3 Nov 2016 16:23:17 +1100 (AEDT)","by ozlabs.org (Postfix, from userid 1003)\n\tid 3t8YK14JYhz9t1Q; Thu,  3 Nov 2016 16:23:17 +1100 (AEDT)"],"Date":"Thu, 3 Nov 2016 16:21:40 +1100","From":"Paul Mackerras <paulus@ozlabs.org>","To":"linuxppc-dev@ozlabs.org","Subject":"[PATCH 3/4] selftests/powerpc/64: Test exception cases in\n\tcopy_tofrom_user","Message-ID":"<20161103052140.GE8368@fergus.ozlabs.ibm.com>","References":"<20161103051949.GC8368@fergus.ozlabs.ibm.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=us-ascii","Content-Disposition":"inline","In-Reply-To":"<20161103051949.GC8368@fergus.ozlabs.ibm.com>","User-Agent":"Mutt/1.5.24 (2015-08-30)","X-BeenThere":"linuxppc-dev@lists.ozlabs.org","X-Mailman-Version":"2.1.23","Precedence":"list","List-Id":"Linux on PowerPC Developers Mail List\n\t<linuxppc-dev.lists.ozlabs.org>","List-Unsubscribe":"<https://lists.ozlabs.org/options/linuxppc-dev>,\n\t<mailto:linuxppc-dev-request@lists.ozlabs.org?subject=unsubscribe>","List-Archive":"<http://lists.ozlabs.org/pipermail/linuxppc-dev/>","List-Post":"<mailto:linuxppc-dev@lists.ozlabs.org>","List-Help":"<mailto:linuxppc-dev-request@lists.ozlabs.org?subject=help>","List-Subscribe":"<https://lists.ozlabs.org/listinfo/linuxppc-dev>,\n\t<mailto:linuxppc-dev-request@lists.ozlabs.org?subject=subscribe>","Errors-To":"linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org","Sender":"\"Linuxppc-dev\"\n\t<linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org>"},"content":"From: Michael Ellerman <mpe@ellerman.id.au>\n\nThis adds a set of test cases to test the behaviour of\ncopy_tofrom_user when exceptions are encountered accessing the\nsource or destination.  Currently, copy_tofrom_user does not always\ncopy as many bytes as possible when an exception occurs on a store\nto the destination, and that is reflected in failures in these tests.\n\nBased on a test program from Anton Blanchard.\n\n[paulus@ozlabs.org - test all three paths, wrote commit description]\n\nSigned-off-by: Paul Mackerras <paulus@ozlabs.org>\n---\n tools/testing/selftests/powerpc/copyloops/Makefile |  11 +-\n .../selftests/powerpc/copyloops/asm/ppc_asm.h      |  22 +---\n .../powerpc/copyloops/copy_tofrom_user_reference.S |  24 +++++\n .../selftests/powerpc/copyloops/exc_validate.c     | 117 +++++++++++++++++++++\n tools/testing/selftests/powerpc/copyloops/stubs.S  |  19 ++++\n 5 files changed, 173 insertions(+), 20 deletions(-)\n create mode 100644 tools/testing/selftests/powerpc/copyloops/copy_tofrom_user_reference.S\n create mode 100644 tools/testing/selftests/powerpc/copyloops/exc_validate.c\n create mode 100644 tools/testing/selftests/powerpc/copyloops/stubs.S","diff":"diff --git a/tools/testing/selftests/powerpc/copyloops/Makefile b/tools/testing/selftests/powerpc/copyloops/Makefile\nindex 1b351c3..feb7bf1 100644\n--- a/tools/testing/selftests/powerpc/copyloops/Makefile\n+++ b/tools/testing/selftests/powerpc/copyloops/Makefile\n@@ -10,9 +10,10 @@ ASFLAGS = $(CFLAGS)\n TEST_PROGS :=\tcopyuser_64_t0 copyuser_64_t1 copyuser_64_t2 \\\n \t\tcopyuser_p7_t0 copyuser_p7_t1 \\\n \t\tmemcpy_64_t0 memcpy_64_t1 memcpy_64_t2 \\\n-\t\tmemcpy_p7_t0 memcpy_p7_t1\n+\t\tmemcpy_p7_t0 memcpy_p7_t1 \\\n+\t\tcopyuser_64_exc_t0 copyuser_64_exc_t1 copyuser_64_exc_t2\n \n-EXTRA_SOURCES := validate.c ../harness.c\n+EXTRA_SOURCES := validate.c ../harness.c stubs.S\n \n all: $(TEST_PROGS)\n \n@@ -37,6 +38,12 @@ memcpy_p7_t%:\tmemcpy_power7.S $(EXTRA_SOURCES)\n \t\t-D COPY_LOOP=test_memcpy_power7 \\\n \t\t-D SELFTEST_CASE=$(subst memcpy_p7_t,,$@) -o $@ $^\n \n+copyuser_64_exc_t%: copyuser_64.S exc_validate.c ../harness.c \\\n+\t\tcopy_tofrom_user_reference.S stubs.S\n+\t$(CC) $(CPPFLAGS) $(CFLAGS) \\\n+\t\t-D COPY_LOOP=test___copy_tofrom_user_base \\\n+\t\t-D SELFTEST_CASE=$(subst copyuser_64_exc_t,,$@) -o $@ $^\n+\n include ../../lib.mk\n \n clean:\ndiff --git a/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h b/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h\nindex 7eb0cd6..03f10f1 100644\n--- a/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h\n+++ b/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h\n@@ -1,3 +1,5 @@\n+#ifndef __SELFTESTS_POWERPC_PPC_ASM_H\n+#define __SELFTESTS_POWERPC_PPC_ASM_H\n #include <ppc-asm.h>\n \n #define CONFIG_ALTIVEC\n@@ -25,24 +27,6 @@\n \n #define PPC_MTOCRF(A, B)\tmtocrf A, B\n \n-FUNC_START(enter_vmx_usercopy)\n-\tli\tr3,1\n-\tblr\n-\n-FUNC_START(exit_vmx_usercopy)\n-\tli\tr3,0\n-\tblr\n-\n-FUNC_START(enter_vmx_copy)\n-\tli\tr3,1\n-\tblr\n-\n-FUNC_START(exit_vmx_copy)\n-\tblr\n-\n-FUNC_START(__copy_tofrom_user_base)\n-\tblr\n-\n #define BEGIN_FTR_SECTION\t\t.if test_feature\n #define FTR_SECTION_ELSE\t\t.else\n #define ALT_FTR_SECTION_END_IFCLR(x)\t.endif\n@@ -53,3 +37,5 @@ FUNC_START(__copy_tofrom_user_base)\n \n /* Default to taking the first of any alternative feature sections */\n test_feature = 1\n+\n+#endif /* __SELFTESTS_POWERPC_PPC_ASM_H */\ndiff --git a/tools/testing/selftests/powerpc/copyloops/copy_tofrom_user_reference.S b/tools/testing/selftests/powerpc/copyloops/copy_tofrom_user_reference.S\nnew file mode 100644\nindex 0000000..3363b86\n--- /dev/null\n+++ b/tools/testing/selftests/powerpc/copyloops/copy_tofrom_user_reference.S\n@@ -0,0 +1,24 @@\n+#include <asm/ppc_asm.h>\n+\n+_GLOBAL(copy_tofrom_user_reference)\n+\tcmpdi\tr5,0\n+\tbeq\t4f\n+\n+\tmtctr\tr5\n+\n+1:\tlbz\tr6,0(r4)\n+2:\tstb\tr6,0(r3)\n+\taddi\tr3,r3,1\n+\taddi\tr4,r4,1\n+\tbdnz\t1b\n+\n+3:\tmfctr\tr3\n+\tblr\n+\n+4:\tmr\tr3,r5\n+\tblr\n+\n+.section __ex_table,\"a\"\n+\t.llong\t1b,3b\n+\t.llong\t2b,3b\n+.text\ndiff --git a/tools/testing/selftests/powerpc/copyloops/exc_validate.c b/tools/testing/selftests/powerpc/copyloops/exc_validate.c\nnew file mode 100644\nindex 0000000..72e7830\n--- /dev/null\n+++ b/tools/testing/selftests/powerpc/copyloops/exc_validate.c\n@@ -0,0 +1,117 @@\n+#include <stdlib.h>\n+#include <string.h>\n+#include <stdio.h>\n+#include <signal.h>\n+#include <unistd.h>\n+#include <sys/mman.h>\n+\n+extern char __start___ex_table[];\n+extern char __stop___ex_table[];\n+\n+#if defined(__powerpc64__)\n+#define UCONTEXT_NIA(UC)\t(UC)->uc_mcontext.gp_regs[PT_NIP]\n+#elif defined(__powerpc__)\n+#define UCONTEXT_NIA(UC)\t(UC)->uc_mcontext.uc_regs->gregs[PT_NIP]\n+#else\n+#error implement UCONTEXT_NIA\n+#endif\n+\n+static void segv_handler(int signr, siginfo_t *info, void *ptr)\n+{\n+\tucontext_t *uc = (ucontext_t *)ptr;\n+\tunsigned long addr = (unsigned long)info->si_addr;\n+\tunsigned long *ip = &UCONTEXT_NIA(uc);\n+\tunsigned long *ex_p = (unsigned long *)__start___ex_table;\n+\n+\twhile (ex_p < (unsigned long *)__stop___ex_table) {\n+\t\tunsigned long insn, fixup;\n+\n+\t\tinsn = *ex_p++;\n+\t\tfixup = *ex_p++;\n+\n+\t\tif (insn == *ip) {\n+\t\t\t*ip = fixup;\n+\t\t\treturn;\n+\t\t}\n+\t}\n+\n+\tprintf(\"No exception table match for NIA %lx ADDR %lx\\n\", *ip, addr);\n+\tabort();\n+}\n+\n+static void setup_segv_handler(void)\n+{\n+\tstruct sigaction action;\n+\n+\tmemset(&action, 0, sizeof(action));\n+\taction.sa_sigaction = segv_handler;\n+\taction.sa_flags = SA_SIGINFO;\n+\tsigaction(SIGSEGV, &action, NULL);\n+}\n+\n+unsigned long COPY_LOOP(void *to, const void *from, unsigned long size);\n+unsigned long test_copy_tofrom_user_reference(void *to, const void *from, unsigned long size);\n+\n+static int total_passed;\n+static int total_failed;\n+\n+static void do_one_test(char *dstp, char *srcp, unsigned long len)\n+{\n+\tunsigned long got, expected;\n+\n+\tgot = COPY_LOOP(dstp, srcp, len);\n+\texpected = test_copy_tofrom_user_reference(dstp, srcp, len);\n+\n+\tif (got != expected) {\n+\t\ttotal_failed++;\n+\t\tprintf(\"FAIL from=%p to=%p len=%ld returned %ld, expected %ld\\n\",\n+\t\t       srcp, dstp, len, got, expected);\n+\t\t//abort();\n+\t} else\n+\t\ttotal_passed++;\n+}\n+\n+//#define MAX_LEN 512\n+#define MAX_LEN 16\n+\n+int main(void)\n+{\n+\tint page_size;\n+\tstatic char *p, *q;\n+\tunsigned long src, dst, len;\n+\n+\tpage_size = getpagesize();\n+\tp = mmap(NULL, page_size * 2, PROT_READ|PROT_WRITE,\n+\t\tMAP_PRIVATE|MAP_ANONYMOUS, -1, 0);\n+\n+\tif (p == MAP_FAILED) {\n+\t\tperror(\"mmap\");\n+\t\texit(1);\n+\t}\n+\n+\tmemset(p, 0, page_size);\n+\n+\tsetup_segv_handler();\n+\n+\tif (mprotect(p + page_size, page_size, PROT_NONE)) {\n+\t\tperror(\"mprotect\");\n+\t\texit(1);\n+\t}\n+\n+\tq = p + page_size - MAX_LEN;\n+\n+\tfor (src = 0; src < MAX_LEN; src++) {\n+\t\tfor (dst = 0; dst < MAX_LEN; dst++) {\n+\t\t\tfor (len = 0; len < MAX_LEN+1; len++) {\n+\t\t\t\t// printf(\"from=%p to=%p len=%ld\\n\", q+dst, q+src, len);\n+\t\t\t\tdo_one_test(q+dst, q+src, len);\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\tprintf(\"Totals:\\n\");\n+\tprintf(\"  Pass: %d\\n\", total_passed);\n+\tprintf(\"  Fail: %d\\n\", total_failed);\n+\n+\treturn 0;\n+}\ndiff --git a/tools/testing/selftests/powerpc/copyloops/stubs.S b/tools/testing/selftests/powerpc/copyloops/stubs.S\nnew file mode 100644\nindex 0000000..830e2a6\n--- /dev/null\n+++ b/tools/testing/selftests/powerpc/copyloops/stubs.S\n@@ -0,0 +1,19 @@\n+#include <asm/ppc_asm.h>\n+\n+FUNC_START(enter_vmx_usercopy)\n+\tli\tr3,1\n+\tblr\n+\n+FUNC_START(exit_vmx_usercopy)\n+\tli\tr3,0\n+\tblr\n+\n+FUNC_START(enter_vmx_copy)\n+\tli\tr3,1\n+\tblr\n+\n+FUNC_START(exit_vmx_copy)\n+\tblr\n+\n+FUNC_START(__copy_tofrom_user_base)\n+\tblr\n","prefixes":["3/4"]}