xref: /qemu/tests/tcg/s390x/noexec.c (revision 8f9abdf5)
1 #include "../multiarch/noexec.c.inc"
2 
3 static void *arch_mcontext_pc(const mcontext_t *ctx)
4 {
5     return (void *)ctx->psw.addr;
6 }
7 
8 static int arch_mcontext_arg(const mcontext_t *ctx)
9 {
10     return ctx->gregs[2];
11 }
12 
13 static void arch_flush(void *p, int len)
14 {
15 }
16 
17 extern char noexec_1[];
18 extern char noexec_2[];
19 extern char noexec_end[];
20 
21 asm("noexec_1:\n"
22     "   lgfi %r2,1\n"       /* %r2 is 0 on entry, set 1. */
23     "noexec_2:\n"
24     "   lgfi %r2,2\n"       /* %r2 is 0/1; set 2. */
25     "   br %r14\n"          /* return */
26     "noexec_end:");
27 
28 extern char exrl_1[];
29 extern char exrl_2[];
30 extern char exrl_end[];
31 
32 asm("exrl_1:\n"
33     "   exrl %r0, exrl_2\n"
34     "   br %r14\n"
35     "exrl_2:\n"
36     "   lgfi %r2,2\n"
37     "exrl_end:");
38 
39 int main(void)
40 {
41     struct noexec_test noexec_tests[] = {
42         {
43             .name = "fallthrough",
44             .test_code = noexec_1,
45             .test_len = noexec_end - noexec_1,
46             .page_ofs = noexec_1 - noexec_2,
47             .entry_ofs = noexec_1 - noexec_2,
48             .expected_si_ofs = 0,
49             .expected_pc_ofs = 0,
50             .expected_arg = 1,
51         },
52         {
53             .name = "jump",
54             .test_code = noexec_1,
55             .test_len = noexec_end - noexec_1,
56             .page_ofs = noexec_1 - noexec_2,
57             .entry_ofs = 0,
58             .expected_si_ofs = 0,
59             .expected_pc_ofs = 0,
60             .expected_arg = 0,
61         },
62         {
63             .name = "exrl",
64             .test_code = exrl_1,
65             .test_len = exrl_end - exrl_1,
66             .page_ofs = exrl_1 - exrl_2,
67             .entry_ofs = exrl_1 - exrl_2,
68             .expected_si_ofs = 0,
69             .expected_pc_ofs = exrl_1 - exrl_2,
70             .expected_arg = 0,
71         },
72         {
73             .name = "fallthrough [cross]",
74             .test_code = noexec_1,
75             .test_len = noexec_end - noexec_1,
76             .page_ofs = noexec_1 - noexec_2 - 2,
77             .entry_ofs = noexec_1 - noexec_2 - 2,
78             .expected_si_ofs = 0,
79             .expected_pc_ofs = -2,
80             .expected_arg = 1,
81         },
82         {
83             .name = "jump [cross]",
84             .test_code = noexec_1,
85             .test_len = noexec_end - noexec_1,
86             .page_ofs = noexec_1 - noexec_2 - 2,
87             .entry_ofs = -2,
88             .expected_si_ofs = 0,
89             .expected_pc_ofs = -2,
90             .expected_arg = 0,
91         },
92         {
93             .name = "exrl [cross]",
94             .test_code = exrl_1,
95             .test_len = exrl_end - exrl_1,
96             .page_ofs = exrl_1 - exrl_2 - 2,
97             .entry_ofs = exrl_1 - exrl_2 - 2,
98             .expected_si_ofs = 0,
99             .expected_pc_ofs = exrl_1 - exrl_2 - 2,
100             .expected_arg = 0,
101         },
102     };
103 
104     return test_noexec(noexec_tests,
105                        sizeof(noexec_tests) / sizeof(noexec_tests[0]));
106 }
107