Bring in FreeBSD's stress2 stress testing suite.
[dragonfly.git] / test / stress / stress2 / misc / ldt.sh
1 #!/bin/sh
2
3 #
4 # Copyright (c) 2009 Peter Holm <pho@FreeBSD.org>
5 # All rights reserved.
6 #
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
9 # are met:
10 # 1. Redistributions of source code must retain the above copyright
11 #    notice, this list of conditions and the following disclaimer.
12 # 2. Redistributions in binary form must reproduce the above copyright
13 #    notice, this list of conditions and the following disclaimer in the
14 #    documentation and/or other materials provided with the distribution.
15 #
16 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 # ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 # SUCH DAMAGE.
27 #
28 # $FreeBSD$
29 #
30
31 # Test the amd64 implementation of:
32 # 1. Per-process private ldt and corresponding i386 arch syscalls.
33 # 2. Per-process private io permission bitmap and corresponding
34 #    i386 arch syscalls.
35 # 3. Sigcontext
36
37 # The tests must be compiled on i386 and run on amd64
38
39 # All tests by kib@
40
41 [ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
42
43 cd /tmp
44 if [ "`uname -p`" = "i386" ]; then
45         cat > ldt.c <<EOF
46 /* \$Id: ldt.c,v 1.8 2008/11/01 21:14:59 kostik Exp kostik \$ */
47
48 #include <sys/param.h>
49 #include <sys/types.h>
50 #include <sys/wait.h>
51 #include <machine/segments.h>
52 #include <machine/sysarch.h>
53 #include <errno.h>
54 #include <inttypes.h>
55 #include <signal.h>
56 #include <stdio.h>
57 #include <string.h>
58 #include <unistd.h>
59
60 char stack[64 * 1024];
61
62 char a[1];
63
64 int
65 s2ds(int sel)
66 {
67
68         return (LSEL(sel, SEL_UPL));
69 }
70
71 unsigned char
72 readbyte(int sel, int offset)
73 {
74         unsigned char res;
75
76         __asm__ volatile(
77             "\tpushl    %%es\n"
78             "\tmovl     %1,%%es\n"
79             "\tmovb     %%es:(%2),%0\n"
80             "\tpopl     %%es\n"
81             : "=r"(res) : "r"(s2ds(sel)), "r"(offset));
82
83         return (res);
84 }
85
86 void
87 writebyte(int sel, int offset, unsigned char val)
88 {
89
90         __asm__ volatile(
91             "\tpushl    %%es\n"
92             "\tmovl     %0,%%es\n"
93             "\tmovb     %2,%%es:(%1)\n"
94             "\tpopl     %%es\n"
95             : : "r"(s2ds(sel)), "r"(offset), "r"(val) : "memory");
96 }
97
98 int
99 alloc_sel(char *base, size_t len, int type, int p)
100 {
101         int sel;
102         union descriptor descs[1], descsk[1];
103         uintptr_t pb;
104
105         memset(descs, 0, sizeof(descs));
106         if (len > PAGE_SIZE) {
107                 len = roundup(len, PAGE_SIZE);
108                 len /= PAGE_SIZE;
109                 descs[0].sd.sd_lolimit = len & 0xffff;
110                 descs[0].sd.sd_hilimit = (len >> 16) & 0xf;
111                 descs[0].sd.sd_gran = 1;
112         } else {
113                 descs[0].sd.sd_lolimit = len;
114                 descs[0].sd.sd_hilimit = 0;
115                 descs[0].sd.sd_gran = 0;
116         }
117         pb = (uintptr_t)base;
118         descs[0].sd.sd_lobase = pb & 0xffffff;
119         descs[0].sd.sd_hibase = (pb >> 24) & 0xff;
120         descs[0].sd.sd_type = type;
121         descs[0].sd.sd_dpl = SEL_UPL;
122         descs[0].sd.sd_p = p;
123         descs[0].sd.sd_def32 = 1;
124
125         if ((sel = i386_set_ldt(LDT_AUTO_ALLOC, descs, 1)) == -1)
126                 fprintf(stderr, "i386_set_ldt: %s\n", strerror(errno));
127         else if (i386_get_ldt(sel, descsk, 1) == -1) {
128                 fprintf(stderr, "i386_get_ldt: %s\n", strerror(errno));
129                 sel = -1;
130         } else if (memcmp(descs, descsk, sizeof(descs)) != 0) {
131                 fprintf(stderr, "descs != descsk\n");
132                 sel = -1;
133         } else
134                 fprintf(stderr, "selector %d\n", sel);
135
136         return (sel);
137 }
138
139 int
140 test1(int tnum, int sel)
141 {
142         unsigned char ar;
143
144         writebyte(sel, 0, '1');
145         ar = readbyte(sel, 0);
146         if (ar == '1')
147                 fprintf(stderr, "test %d.1 ok\n", tnum);
148         else
149                 fprintf(stderr, "test%d.1 failed, ar %x\n", tnum, ar);
150         writebyte(sel, 0, '2');
151         ar = readbyte(sel, 0);
152         if (ar == '2')
153                 fprintf(stderr, "test %d.2 ok\n", tnum);
154         else
155                 fprintf(stderr, "test%d.2 failed, ar %x\n", tnum, ar);
156         return (sel);
157 }
158
159 int
160 test2_func(void *arg)
161 {
162         int *sel;
163
164         sel = arg;
165         test1(2, *sel);
166         rfork(0);
167         test1(3, *sel);
168         return (0);
169 }
170
171 void
172 test2(int sel)
173 {
174         pid_t r;
175         int status;
176
177         r = rfork_thread(RFPROC | RFMEM, stack + sizeof(stack),
178             test2_func, &sel);
179         if (r == -1) {
180                 fprintf(stderr, "rfork(RFPROC): %s\n", strerror(errno));
181                 return;
182         } else {
183                 waitpid(r, &status, 0);
184                 if (WIFSIGNALED(status)) {
185                         fprintf(stderr, "test2: child terminated by %s\n",
186                             strsignal(WTERMSIG(status)));
187                 }
188         }
189 }
190
191 int
192 main(int argc, char *argv[])
193 {
194         int sel;
195
196         sel = alloc_sel(a, 1, SDT_MEMRWA, 1);
197         if (sel == -1)
198                 return (1);
199
200         test1(1, sel);
201         test2(sel);
202         return (0);
203 }
204 EOF
205         cc -o ldt_static_i386 -Wall -static ldt.c
206         rm ldt.c
207
208         cat > ioperm.c <<EOF
209 /* \$Id: ioperm.c,v 1.3 2008/11/02 15:43:33 kostik Exp \$ */
210
211 #include <machine/sysarch.h>
212 #include <errno.h>
213 #include <signal.h>
214 #include <stdio.h>
215 #include <stdlib.h>
216 #include <string.h>
217
218 static const unsigned int port_num = 0x130;
219
220 unsigned char
221 inb(unsigned int port)
222 {
223         unsigned char data;
224
225         __asm __volatile("inb %%dx,%0" : "=a" (data) : "d" (port));
226         return (data);
227 }
228
229 void
230 sigbus_handler(int signo)
231 {
232
233         fprintf(stderr, "Got SIGBUS\n");
234         exit(0);
235 }
236
237 int
238 main(int argc, char *argv[])
239 {
240         struct sigaction sa;
241         unsigned int length1;
242         int enable1;
243
244         if (i386_get_ioperm(port_num, &length1, &enable1) == -1) {
245                 fprintf(stderr, "get 1: %s\n", strerror(errno));
246                 return (1);
247         }
248         if (length1 != 0 && enable1 != 0) {
249                 fprintf(stderr, "enable1: enabled\n");
250                 return (1);
251         }
252         if (i386_set_ioperm(port_num, 1, 1) == -1) {
253                 fprintf(stderr, "set 1: %s\n", strerror(errno));
254                 return (1);
255         }
256         inb(port_num);
257         if (i386_set_ioperm(port_num, 1, 0) == -1) {
258                 fprintf(stderr, "set 2: %s\n", strerror(errno));
259                 return (1);
260         }
261         if (i386_get_ioperm(port_num, &length1, &enable1) == -1) {
262                 fprintf(stderr, "get 1: %s\n", strerror(errno));
263                 return (1);
264         }
265         if (enable1 != 0) {
266                 fprintf(stderr, "enable2: enabled\n");
267                 return (1);
268         }
269         fprintf(stderr, "And now we should get SIGBUS\n");
270         memset(&sa, 0, sizeof(sa));
271         sa.sa_handler = sigbus_handler;
272         if (sigaction(SIGBUS, &sa, NULL) == -1) {
273                 fprintf(stderr, "sigaction(SIGBUS): %s\n", strerror(errno));
274                 return (1);
275         }
276         inb(port_num);
277
278         return (0);
279 }
280 EOF
281         cc -o ioperm_static_i386 -Wall -static ioperm.c
282         rm ioperm.c
283
284         cat > fault.c <<EOF
285 /* \$Id: fault.c,v 1.5 2008/10/28 17:39:16 kostik Exp \$ */
286
287 #include <sys/cdefs.h>
288 #include <sys/types.h>
289 #include <sys/ucontext.h>
290 #include <errno.h>
291 #include <signal.h>
292 #include <stdio.h>
293 #include <string.h>
294 #include <unistd.h>
295
296 extern char *fault_instr;
297 int run;
298
299 void
300 sigsegv_sigaction(int signo, siginfo_t *si, void *c)
301 {
302         ucontext_t *uc;
303         mcontext_t *mc;
304
305         uc = c;
306         mc = &uc->uc_mcontext;
307         printf("SIGSEGV run %d err %x ds %x ss %x es %x fs %x gs %x\n",
308             run, mc->mc_err, mc->mc_ds, mc->mc_ss, mc->mc_es, mc->mc_fs,
309             mc->mc_gs);
310         switch (run) {
311         case 0:
312                 mc->mc_ds = 0x1111;
313                 break;
314         case 1:
315                 mc->mc_es = 0x1111;
316                 break;
317         case 2:
318                 mc->mc_fs = 0x1111;
319                 break;
320         case 3:
321                 mc->mc_gs = 0x1111;
322                 break;
323         case 4:
324                 mc->mc_ss = 0x1111;
325                 break;
326         case 5:
327                 _exit(11);
328         }
329         run++;
330 }
331
332 void
333 fault(void)
334 {
335
336         __asm__ volatile(".globl\tfault_instr;fault_instr:\ttestl\t\$0,0\n");
337 }
338
339 int
340 main(int argc, char *argv[])
341 {
342         struct sigaction sa;
343
344         memset(&sa, 0, sizeof(sa));
345         sa.sa_sigaction = sigsegv_sigaction;
346         sa.sa_flags = SA_SIGINFO;
347         if (sigaction(SIGSEGV, &sa, NULL) == -1) {
348                 fprintf(stderr, "sigaction: %s\n", strerror(errno));
349                 return (1);
350         }
351         if (sigaction(SIGBUS, &sa, NULL) == -1) {
352                 fprintf(stderr, "sigaction: %s\n", strerror(errno));
353                 return (1);
354         }
355
356         fault();
357
358         return (0);
359 }
360 EOF
361         cc -o fault_static_i386 -Wall -static fault.c
362         rm fault.c
363 fi
364
365 if [ "`uname -p`" = "amd64" ]; then
366         [ -x ldt_static_i386 ]    && ./ldt_static_i386
367         [ -x ioperm_static_i386 ] && ./ioperm_static_i386
368         [ -x fault_static_i386 ]  && ./fault_static_i386
369 fi