diff mbox series

[3/3] powerpc/sstep: Always test lmw and stmw

Message ID 20210225032108.1458352-3-jniethe5@gmail.com (mailing list archive)
State Changes Requested
Headers show
Series [1/3] powernv/memtrace: Allow mmaping trace buffers | expand

Checks

Context Check Description
snowpatch_ozlabs/apply_patch warning Failed to apply on branch powerpc/merge (626a6c3d2e20da80aaa710104f34ea6037b28b33)
snowpatch_ozlabs/apply_patch success Successfully applied on branch powerpc/next (6895c5ba7bdcc55eacad03cf309ab23be63b9cac)
snowpatch_ozlabs/build-ppc64le success Build succeeded
snowpatch_ozlabs/build-ppc64be success Build succeeded
snowpatch_ozlabs/build-ppc64e success Build succeeded
snowpatch_ozlabs/build-pmac32 success Build succeeded
snowpatch_ozlabs/checkpatch success total: 0 errors, 0 warnings, 0 checks, 125 lines checked
snowpatch_ozlabs/needsstable success Patch has no Fixes tags

Commit Message

Jordan Niethe Feb. 25, 2021, 3:21 a.m. UTC
Load Multiple Word (lmw) and Store Multiple Word (stmw) will raise an
Alignment Exception:
  - Little Endian mode: always
  - Big Endian mode: address not word aligned

These conditions do not depend on cache inhibited memory. Test the
alignment handler emulation of these instructions regardless of if there
is cache inhibited memory available or not.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
 .../powerpc/alignment/alignment_handler.c     | 96 ++++++++++++++++++-
 1 file changed, 94 insertions(+), 2 deletions(-)

Comments

Michael Ellerman April 1, 2021, 1:39 p.m. UTC | #1
Hi Jordan,

Jordan Niethe <jniethe5@gmail.com> writes:
> Load Multiple Word (lmw) and Store Multiple Word (stmw) will raise an
> Alignment Exception:
>   - Little Endian mode: always
>   - Big Endian mode: address not word aligned
>
> These conditions do not depend on cache inhibited memory. Test the
> alignment handler emulation of these instructions regardless of if there
> is cache inhibited memory available or not.
>
> Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> ---
>  .../powerpc/alignment/alignment_handler.c     | 96 ++++++++++++++++++-
>  1 file changed, 94 insertions(+), 2 deletions(-)

Because of dd3a44c06f7b ("selftests/powerpc: Only test lwm/stmw on big endian")
this will need a respin sorry.

You'll need to add macros to generate lmw/stmw using .long, to avoid the
bug fixed in that commit.

cheers
Jordan Niethe April 6, 2021, 2:04 a.m. UTC | #2
On Fri, Apr 2, 2021 at 12:39 AM Michael Ellerman <mpe@ellerman.id.au> wrote:
>
> Hi Jordan,
>
> Jordan Niethe <jniethe5@gmail.com> writes:
> > Load Multiple Word (lmw) and Store Multiple Word (stmw) will raise an
> > Alignment Exception:
> >   - Little Endian mode: always
> >   - Big Endian mode: address not word aligned
> >
> > These conditions do not depend on cache inhibited memory. Test the
> > alignment handler emulation of these instructions regardless of if there
> > is cache inhibited memory available or not.
> >
> > Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
> > ---
> >  .../powerpc/alignment/alignment_handler.c     | 96 ++++++++++++++++++-
> >  1 file changed, 94 insertions(+), 2 deletions(-)
>
> Because of dd3a44c06f7b ("selftests/powerpc: Only test lwm/stmw on big endian")
> this will need a respin sorry.
>
> You'll need to add macros to generate lmw/stmw using .long, to avoid the
> bug fixed in that commit.
Thanks, I will resend.
>
> cheers
diff mbox series

Patch

diff --git a/tools/testing/selftests/powerpc/alignment/alignment_handler.c b/tools/testing/selftests/powerpc/alignment/alignment_handler.c
index f5eb5b85a2cf..c3003f95e043 100644
--- a/tools/testing/selftests/powerpc/alignment/alignment_handler.c
+++ b/tools/testing/selftests/powerpc/alignment/alignment_handler.c
@@ -45,6 +45,7 @@ 
 #include <getopt.h>
 #include <setjmp.h>
 #include <signal.h>
+#include <errno.h>
 
 #include "utils.h"
 #include "instructions.h"
@@ -434,7 +435,6 @@  int test_alignment_handler_integer(void)
 	LOAD_DFORM_TEST(ldu);
 	LOAD_XFORM_TEST(ldx);
 	LOAD_XFORM_TEST(ldux);
-	LOAD_DFORM_TEST(lmw);
 	STORE_DFORM_TEST(stb);
 	STORE_XFORM_TEST(stbx);
 	STORE_DFORM_TEST(stbu);
@@ -453,7 +453,6 @@  int test_alignment_handler_integer(void)
 	STORE_XFORM_TEST(stdx);
 	STORE_DFORM_TEST(stdu);
 	STORE_XFORM_TEST(stdux);
-	STORE_DFORM_TEST(stmw);
 
 	return rc;
 }
@@ -599,6 +598,97 @@  int test_alignment_handler_fp_prefix(void)
 	return rc;
 }
 
+int test_alignment_handler_multiple(void)
+{
+	int offset, width, r, rc = 0;
+	void *src1, *dst1, *src2, *dst2;
+
+	rc = posix_memalign(&src1, bufsize, bufsize);
+	if (rc) {
+		printf("\n");
+		return rc;
+	}
+
+	rc = posix_memalign(&dst1, bufsize, bufsize);
+	if (rc) {
+		printf("\n");
+		free(src1);
+		return rc;
+	}
+
+	src2 = malloc(bufsize);
+	if (!src2) {
+		printf("\n");
+		free(src1);
+		free(dst1);
+		return -ENOMEM;
+	}
+
+	dst2 = malloc(bufsize);
+	if (!dst2) {
+		printf("\n");
+		free(src1);
+		free(dst1);
+		free(src2);
+		return -ENOMEM;
+	}
+
+	/* lmw */
+	width = 4;
+	printf("\tDoing lmw:\t");
+	for (offset = 0; offset < width; offset++) {
+		preload_data(src1, offset, width);
+		preload_data(src2, offset, width);
+
+		asm volatile("lmw  31, 0(%0) ; std 31, 0(%1)"
+			     :: "r"(src1 + offset), "r"(dst1 + offset), "r"(0)
+			     : "memory", "r31");
+
+		memcpy(dst2 + offset, src1 + offset, width);
+
+		r = test_memcmp(dst1, dst2, width, offset, "test_lmw");
+		if (r && !debug) {
+			printf("FAILED: Wrong Data\n");
+			break;
+		}
+	}
+
+	if (!r)
+		printf("PASSED\n");
+	else
+		rc |= 1;
+
+	/* stmw */
+	width = 4;
+	printf("\tDoing stmw:\t");
+	for (offset = 0; offset < width; offset++) {
+		preload_data(src1, offset, width);
+		preload_data(src2, offset, width);
+
+		asm volatile("ld  31, 0(%0) ; stmw 31, 0(%1)"
+			     :: "r"(src1 + offset), "r"(dst1 + offset), "r"(0)
+			     : "memory", "r31");
+
+		memcpy(dst2 + offset, src1 + offset, width);
+
+		r = test_memcmp(dst1, dst2, width, offset, "test_stmw");
+		if (r && !debug) {
+			printf("FAILED: Wrong Data\n");
+			break;
+		}
+	}
+	if (!r)
+		printf("PASSED\n");
+	else
+		rc |= 1;
+
+	free(src1);
+	free(src2);
+	free(dst1);
+	free(dst2);
+	return rc;
+}
+
 void usage(char *prog)
 {
 	printf("Usage: %s [options] [path [offset]]\n", prog);
@@ -673,5 +763,7 @@  int main(int argc, char *argv[])
 			   "test_alignment_handler_fp_206");
 	rc |= test_harness(test_alignment_handler_fp_prefix,
 			   "test_alignment_handler_fp_prefix");
+	rc |= test_harness(test_alignment_handler_multiple,
+			   "test_alignment_handler_multiple");
 	return rc;
 }