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