xref: /linux/tools/testing/selftests/powerpc/copyloops/validate.c (revision 498495dba268b20e8eadd7fe93c140c68b6cc9d2)
1*b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
222d651dcSMichael Ellerman #include <malloc.h>
322d651dcSMichael Ellerman #include <string.h>
422d651dcSMichael Ellerman #include <stdlib.h>
522d651dcSMichael Ellerman #include <stdbool.h>
622d651dcSMichael Ellerman 
715ec3997SSimon Guo #include "utils.h"
822d651dcSMichael Ellerman 
922d651dcSMichael Ellerman #define MAX_LEN 8192
1022d651dcSMichael Ellerman #define MAX_OFFSET 16
1122d651dcSMichael Ellerman #define MIN_REDZONE 128
1222d651dcSMichael Ellerman #define BUFLEN (MAX_LEN+MAX_OFFSET+2*MIN_REDZONE)
1322d651dcSMichael Ellerman #define POISON 0xa5
1422d651dcSMichael Ellerman 
1522d651dcSMichael Ellerman unsigned long COPY_LOOP(void *to, const void *from, unsigned long size);
1622d651dcSMichael Ellerman 
do_one(char * src,char * dst,unsigned long src_off,unsigned long dst_off,unsigned long len,void * redzone,void * fill)1722d651dcSMichael Ellerman static void do_one(char *src, char *dst, unsigned long src_off,
1822d651dcSMichael Ellerman 		   unsigned long dst_off, unsigned long len, void *redzone,
1922d651dcSMichael Ellerman 		   void *fill)
2022d651dcSMichael Ellerman {
2122d651dcSMichael Ellerman 	char *srcp, *dstp;
2222d651dcSMichael Ellerman 	unsigned long ret;
2322d651dcSMichael Ellerman 	unsigned long i;
2422d651dcSMichael Ellerman 
2522d651dcSMichael Ellerman 	srcp = src + MIN_REDZONE + src_off;
2622d651dcSMichael Ellerman 	dstp = dst + MIN_REDZONE + dst_off;
2722d651dcSMichael Ellerman 
2822d651dcSMichael Ellerman 	memset(src, POISON, BUFLEN);
2922d651dcSMichael Ellerman 	memset(dst, POISON, BUFLEN);
3022d651dcSMichael Ellerman 	memcpy(srcp, fill, len);
3122d651dcSMichael Ellerman 
3222d651dcSMichael Ellerman 	ret = COPY_LOOP(dstp, srcp, len);
3322d651dcSMichael Ellerman 	if (ret && ret != (unsigned long)dstp) {
3422d651dcSMichael Ellerman 		printf("(%p,%p,%ld) returned %ld\n", dstp, srcp, len, ret);
3522d651dcSMichael Ellerman 		abort();
3622d651dcSMichael Ellerman 	}
3722d651dcSMichael Ellerman 
3822d651dcSMichael Ellerman 	if (memcmp(dstp, srcp, len)) {
3922d651dcSMichael Ellerman 		printf("(%p,%p,%ld) miscompare\n", dstp, srcp, len);
4022d651dcSMichael Ellerman 		printf("src: ");
4122d651dcSMichael Ellerman 		for (i = 0; i < len; i++)
4222d651dcSMichael Ellerman 			printf("%02x ", srcp[i]);
4322d651dcSMichael Ellerman 		printf("\ndst: ");
4422d651dcSMichael Ellerman 		for (i = 0; i < len; i++)
4522d651dcSMichael Ellerman 			printf("%02x ", dstp[i]);
4622d651dcSMichael Ellerman 		printf("\n");
4722d651dcSMichael Ellerman 		abort();
4822d651dcSMichael Ellerman 	}
4922d651dcSMichael Ellerman 
5022d651dcSMichael Ellerman 	if (memcmp(dst, redzone, dstp - dst)) {
5122d651dcSMichael Ellerman 		printf("(%p,%p,%ld) redzone before corrupted\n",
5222d651dcSMichael Ellerman 		       dstp, srcp, len);
5322d651dcSMichael Ellerman 		abort();
5422d651dcSMichael Ellerman 	}
5522d651dcSMichael Ellerman 
5622d651dcSMichael Ellerman 	if (memcmp(dstp+len, redzone, dst+BUFLEN-(dstp+len))) {
5722d651dcSMichael Ellerman 		printf("(%p,%p,%ld) redzone after corrupted\n",
5822d651dcSMichael Ellerman 		       dstp, srcp, len);
5922d651dcSMichael Ellerman 		abort();
6022d651dcSMichael Ellerman 	}
6122d651dcSMichael Ellerman }
6222d651dcSMichael Ellerman 
test_copy_loop(void)6322d651dcSMichael Ellerman int test_copy_loop(void)
6422d651dcSMichael Ellerman {
6522d651dcSMichael Ellerman 	char *src, *dst, *redzone, *fill;
6622d651dcSMichael Ellerman 	unsigned long len, src_off, dst_off;
6722d651dcSMichael Ellerman 	unsigned long i;
6822d651dcSMichael Ellerman 
6922d651dcSMichael Ellerman 	src = memalign(BUFLEN, BUFLEN);
7022d651dcSMichael Ellerman 	dst = memalign(BUFLEN, BUFLEN);
7122d651dcSMichael Ellerman 	redzone = malloc(BUFLEN);
7222d651dcSMichael Ellerman 	fill = malloc(BUFLEN);
7322d651dcSMichael Ellerman 
7422d651dcSMichael Ellerman 	if (!src || !dst || !redzone || !fill) {
7522d651dcSMichael Ellerman 		fprintf(stderr, "malloc failed\n");
7622d651dcSMichael Ellerman 		exit(1);
7722d651dcSMichael Ellerman 	}
7822d651dcSMichael Ellerman 
7922d651dcSMichael Ellerman 	memset(redzone, POISON, BUFLEN);
8022d651dcSMichael Ellerman 
8122d651dcSMichael Ellerman 	/* Fill with sequential bytes */
8222d651dcSMichael Ellerman 	for (i = 0; i < BUFLEN; i++)
8322d651dcSMichael Ellerman 		fill[i] = i & 0xff;
8422d651dcSMichael Ellerman 
8522d651dcSMichael Ellerman 	for (len = 1; len < MAX_LEN; len++) {
8622d651dcSMichael Ellerman 		for (src_off = 0; src_off < MAX_OFFSET; src_off++) {
8722d651dcSMichael Ellerman 			for (dst_off = 0; dst_off < MAX_OFFSET; dst_off++) {
8822d651dcSMichael Ellerman 				do_one(src, dst, src_off, dst_off, len,
8922d651dcSMichael Ellerman 				       redzone, fill);
9022d651dcSMichael Ellerman 			}
9122d651dcSMichael Ellerman 		}
9222d651dcSMichael Ellerman 	}
9322d651dcSMichael Ellerman 
9422d651dcSMichael Ellerman 	return 0;
9522d651dcSMichael Ellerman }
9622d651dcSMichael Ellerman 
main(void)9722d651dcSMichael Ellerman int main(void)
9822d651dcSMichael Ellerman {
9922d651dcSMichael Ellerman 	return test_harness(test_copy_loop, str(COPY_LOOP));
10022d651dcSMichael Ellerman }
101