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
)
21 " mvc 0(256,%[dst]),0(%[src])\n"
33 /* register the SIGSEGV handler */
34 if (signal(SIGSEGV
, handle_sigsegv
) == SIG_ERR
) {
35 fprintf(stderr
, "SIGSEGV not registered\n");
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");
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");
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");
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");
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");
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");
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
++) {
92 fprintf(stderr
, "src modified\n");
95 if (i
< 4096 - 128 || i
>= 4096 + 128) {
97 fprintf(stderr
, "wrong dst modified\n");
101 if (dst
[i
] != 0xff) {
102 fprintf(stderr
, "wrong data moved\n");