4 # Copyright (c) 2009 Peter Holm <pho@FreeBSD.org>
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
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.
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
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
37 # The tests must be compiled on i386 and run on amd64
41 [ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
44 if [ "`uname -p`" = "i386" ]; then
46 /* \$Id: ldt.c,v 1.8 2008/11/01 21:14:59 kostik Exp kostik \$ */
48 #include <sys/param.h>
49 #include <sys/types.h>
51 #include <machine/segments.h>
52 #include <machine/sysarch.h>
60 char stack[64 * 1024];
68 return (LSEL(sel, SEL_UPL));
72 readbyte(int sel, int offset)
79 "\tmovb %%es:(%2),%0\n"
81 : "=r"(res) : "r"(s2ds(sel)), "r"(offset));
87 writebyte(int sel, int offset, unsigned char val)
93 "\tmovb %2,%%es:(%1)\n"
95 : : "r"(s2ds(sel)), "r"(offset), "r"(val) : "memory");
99 alloc_sel(char *base, size_t len, int type, int p)
102 union descriptor descs[1], descsk[1];
105 memset(descs, 0, sizeof(descs));
106 if (len > PAGE_SIZE) {
107 len = roundup(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;
113 descs[0].sd.sd_lolimit = len;
114 descs[0].sd.sd_hilimit = 0;
115 descs[0].sd.sd_gran = 0;
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;
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));
130 } else if (memcmp(descs, descsk, sizeof(descs)) != 0) {
131 fprintf(stderr, "descs != descsk\n");
134 fprintf(stderr, "selector %d\n", sel);
140 test1(int tnum, int sel)
144 writebyte(sel, 0, '1');
145 ar = readbyte(sel, 0);
147 fprintf(stderr, "test %d.1 ok\n", tnum);
149 fprintf(stderr, "test%d.1 failed, ar %x\n", tnum, ar);
150 writebyte(sel, 0, '2');
151 ar = readbyte(sel, 0);
153 fprintf(stderr, "test %d.2 ok\n", tnum);
155 fprintf(stderr, "test%d.2 failed, ar %x\n", tnum, ar);
160 test2_func(void *arg)
177 r = rfork_thread(RFPROC | RFMEM, stack + sizeof(stack),
180 fprintf(stderr, "rfork(RFPROC): %s\n", strerror(errno));
183 waitpid(r, &status, 0);
184 if (WIFSIGNALED(status)) {
185 fprintf(stderr, "test2: child terminated by %s\n",
186 strsignal(WTERMSIG(status)));
192 main(int argc, char *argv[])
196 sel = alloc_sel(a, 1, SDT_MEMRWA, 1);
205 cc -o ldt_static_i386 -Wall -static ldt.c
209 /* \$Id: ioperm.c,v 1.3 2008/11/02 15:43:33 kostik Exp \$ */
211 #include <machine/sysarch.h>
218 static const unsigned int port_num = 0x130;
221 inb(unsigned int port)
225 __asm __volatile("inb %%dx,%0" : "=a" (data) : "d" (port));
230 sigbus_handler(int signo)
233 fprintf(stderr, "Got SIGBUS\n");
238 main(int argc, char *argv[])
241 unsigned int length1;
244 if (i386_get_ioperm(port_num, &length1, &enable1) == -1) {
245 fprintf(stderr, "get 1: %s\n", strerror(errno));
248 if (length1 != 0 && enable1 != 0) {
249 fprintf(stderr, "enable1: enabled\n");
252 if (i386_set_ioperm(port_num, 1, 1) == -1) {
253 fprintf(stderr, "set 1: %s\n", strerror(errno));
257 if (i386_set_ioperm(port_num, 1, 0) == -1) {
258 fprintf(stderr, "set 2: %s\n", strerror(errno));
261 if (i386_get_ioperm(port_num, &length1, &enable1) == -1) {
262 fprintf(stderr, "get 1: %s\n", strerror(errno));
266 fprintf(stderr, "enable2: enabled\n");
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));
281 cc -o ioperm_static_i386 -Wall -static ioperm.c
285 /* \$Id: fault.c,v 1.5 2008/10/28 17:39:16 kostik Exp \$ */
287 #include <sys/cdefs.h>
288 #include <sys/types.h>
289 #include <sys/ucontext.h>
296 extern char *fault_instr;
300 sigsegv_sigaction(int signo, siginfo_t *si, void *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,
336 __asm__ volatile(".globl\tfault_instr;fault_instr:\ttestl\t\$0,0\n");
340 main(int argc, char *argv[])
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));
351 if (sigaction(SIGBUS, &sa, NULL) == -1) {
352 fprintf(stderr, "sigaction: %s\n", strerror(errno));
361 cc -o fault_static_i386 -Wall -static fault.c
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