Merge remote-tracking branch 'remotes/cohuck-gitlab/tags/s390x-20210409' into staging
[qemu/ar7.git] / tests / tcg / s390x / mvc.c
blobaa552d52e53d184ab50f3b84c6d332833e424447
1 #include <stdint.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <sys/mman.h>
6 #include <signal.h>
7 #include <setjmp.h>
9 jmp_buf jmp_env;
11 static void handle_sigsegv(int sig)
13 siglongjmp(jmp_env, 1);
16 #define ALLOC_SIZE (2 * 4096)
18 static inline void mvc_256(const char *dst, const char *src)
20 asm volatile (
21 " mvc 0(256,%[dst]),0(%[src])\n"
23 : [dst] "d" (dst),
24 [src] "d" (src)
25 : "memory");
28 int main(void)
30 char *src, *dst;
31 int i;
33 /* register the SIGSEGV handler */
34 if (signal(SIGSEGV, handle_sigsegv) == SIG_ERR) {
35 fprintf(stderr, "SIGSEGV not registered\n");
36 return 1;
39 /* prepare the buffers - two consecutive pages */
40 src = valloc(ALLOC_SIZE);
41 dst = valloc(ALLOC_SIZE);
42 memset(src, 0xff, ALLOC_SIZE);
43 memset(dst, 0x0, ALLOC_SIZE);
45 /* protect the second pages */
46 if (mprotect(src + 4096, 4096, PROT_NONE) ||
47 mprotect(dst + 4096, 4096, PROT_NONE)) {
48 fprintf(stderr, "mprotect failed\n");
49 return 1;
52 /* fault on second destination page */
53 if (sigsetjmp(jmp_env, 1) == 0) {
54 mvc_256(dst + 4096 - 128, src);
55 fprintf(stderr, "fault not triggered\n");
56 return 1;
59 /* fault on second source page */
60 if (sigsetjmp(jmp_env, 1) == 0) {
61 mvc_256(dst, src + 4096 - 128);
62 fprintf(stderr, "fault not triggered\n");
63 return 1;
66 /* fault on second source and second destination page */
67 if (sigsetjmp(jmp_env, 1) == 0) {
68 mvc_256(dst + 4096 - 128, src + 4096 - 128);
69 fprintf(stderr, "fault not triggered\n");
70 return 1;
73 /* restore permissions */
74 if (mprotect(src + 4096, 4096, PROT_READ | PROT_WRITE) ||
75 mprotect(dst + 4096, 4096, PROT_READ | PROT_WRITE)) {
76 fprintf(stderr, "mprotect failed\n");
77 return 1;
80 /* no data must be touched during the faults */
81 for (i = 0; i < ALLOC_SIZE; i++) {
82 if (src[i] != 0xff || dst[i]) {
83 fprintf(stderr, "data modified during a fault\n");
84 return 1;
88 /* test if MVC works now correctly accross page boundaries */
89 mvc_256(dst + 4096 - 128, src + 4096 - 128);
90 for (i = 0; i < ALLOC_SIZE; i++) {
91 if (src[i] != 0xff) {
92 fprintf(stderr, "src modified\n");
93 return 1;
95 if (i < 4096 - 128 || i >= 4096 + 128) {
96 if (dst[i]) {
97 fprintf(stderr, "wrong dst modified\n");
98 return 1;
100 } else {
101 if (dst[i] != 0xff) {
102 fprintf(stderr, "wrong data moved\n");
103 return 1;
108 return 0;