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