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>
8
9jmp_buf jmp_env;
10
11static void handle_sigsegv(int sig)
12{
13 siglongjmp(jmp_env, 1);
14}
15
16#define ALLOC_SIZE (2 * 4096)
17
18static inline void mvc_256(const char *dst, const char *src)
19{
20 asm volatile (
21 " mvc 0(256,%[dst]),0(%[src])\n"
22 :
23 : [dst] "d" (dst),
24 [src] "d" (src)
25 : "memory");
26}
27
28int main(void)
29{
30 char *src, *dst;
31 int i;
32
33
34 if (signal(SIGSEGV, handle_sigsegv) == SIG_ERR) {
35 fprintf(stderr, "SIGSEGV not registered\n");
36 return 1;
37 }
38
39
40 src = valloc(ALLOC_SIZE);
41 dst = valloc(ALLOC_SIZE);
42 memset(src, 0xff, ALLOC_SIZE);
43 memset(dst, 0x0, ALLOC_SIZE);
44
45
46 if (mprotect(src + 4096, 4096, PROT_NONE) ||
47 mprotect(dst + 4096, 4096, PROT_NONE)) {
48 fprintf(stderr, "mprotect failed\n");
49 return 1;
50 }
51
52
53 if (sigsetjmp(jmp_env, 1) == 0) {
54 mvc_256(dst + 4096 - 128, src);
55 fprintf(stderr, "fault not triggered\n");
56 return 1;
57 }
58
59
60 if (sigsetjmp(jmp_env, 1) == 0) {
61 mvc_256(dst, src + 4096 - 128);
62 fprintf(stderr, "fault not triggered\n");
63 return 1;
64 }
65
66
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;
71 }
72
73
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;
78 }
79
80
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;
85 }
86 }
87
88
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;
94 }
95 if (i < 4096 - 128 || i >= 4096 + 128) {
96 if (dst[i]) {
97 fprintf(stderr, "wrong dst modified\n");
98 return 1;
99 }
100 } else {
101 if (dst[i] != 0xff) {
102 fprintf(stderr, "wrong data moved\n");
103 return 1;
104 }
105 }
106 }
107
108 return 0;
109}
110