1#!/bin/sh 2 3# 4# SPDX-License-Identifier: BSD-2-Clause 5# 6# Copyright (c) 2017 Konstantin Belousov <kib@FreeBSD.org> 7# 8# Redistribution and use in source and binary forms, with or without 9# modification, are permitted provided that the following conditions 10# are met: 11# 1. Redistributions of source code must retain the above copyright 12# notice, this list of conditions and the following disclaimer. 13# 2. Redistributions in binary form must reproduce the above copyright 14# notice, this list of conditions and the following disclaimer in the 15# documentation and/or other materials provided with the distribution. 16# 17# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27# SUCH DAMAGE. 28# 29 30# Maxime Villard <max@m00nbsd.net> spotted this problem: 31# Issue with segment registers on freebsd-i386 32 33# Fixed in r323722 34 35[ `uname -m` = "i386" ] || exit 0 36 37. ../default.cfg 38 39cat > /tmp/mvillard_nest.c <<EOF 40/* $Id: mvillard_nest.c,v 1.2 2017/09/15 14:33:30 kostik Exp kostik $ */ 41 42#include <sys/types.h> 43#include <sys/syscall.h> 44#include <sys/ucontext.h> 45#include <machine/atomic.h> 46#include <machine/segments.h> 47#include <machine/sysarch.h> 48#include <err.h> 49#include <pthread.h> 50#include <signal.h> 51#include <time.h> 52#include <string.h> 53#include <unistd.h> 54 55static volatile u_int b, s; 56 57static void * 58dealloc_ldt(void *arg __unused) 59{ 60 u_int sl; 61 62 for (;;) { 63 while (atomic_load_acq_int(&b) == 0) 64 ; 65 sl = s; 66 s = 0; 67 if (sl != 0) 68 i386_set_ldt(sl, NULL, 1); 69 atomic_store_rel_int(&b, 0); 70 } 71 return (NULL); 72} 73 74static void 75func(void) 76{ 77 union descriptor desc; 78 u_int sel, sl; 79 80 bzero(&desc, sizeof(desc)); 81 desc.sd.sd_type = SDT_MEMRWA; 82 desc.sd.sd_dpl = SEL_UPL; 83 desc.sd.sd_p = 1; 84 desc.sd.sd_def32 = 1; 85 desc.sd.sd_gran = 1; 86 desc.sd.sd_lolimit = 0xffff; 87 desc.sd.sd_hilimit = 0xf; 88 sl = i386_set_ldt(LDT_AUTO_ALLOC, &desc, 1); 89 if ((int)sl == -1) 90 err(1, "i386_set_ldt"); 91 sel = LSEL(sl, SEL_UPL); 92 s = sl; 93 __asm volatile("movw\t%w0,%%es" : : "r" (sel)); 94 atomic_store_rel_int(&b, 1); 95 while (atomic_load_acq_int(&b) != 0) 96 ; 97 getpid(); 98} 99 100static void 101sigsegv_handler(int signo __unused, siginfo_t *si __unused, void *rctx) 102{ 103 ucontext_t *uc; 104 105 uc = rctx; 106 uc->uc_mcontext.mc_es = uc->uc_mcontext.mc_ds; 107} 108 109int 110main(void) 111{ 112 pthread_t thr; 113 time_t start; 114 struct sigaction sa; 115 int error; 116 117 bzero(&sa, sizeof(sa)); 118 sa.sa_sigaction = sigsegv_handler; 119 sa.sa_flags = SA_SIGINFO; 120 error = sigaction(SIGSEGV, &sa, NULL); 121 if (error != 0) 122 err(1, "sigaction SIGSEGV"); 123 error = sigaction(SIGBUS, &sa, NULL); 124 if (error != 0) 125 err(1, "sigaction SIGBUS"); 126 127 error = pthread_create(&thr, NULL, dealloc_ldt, NULL); 128 if (error != 0) 129 errc(1, error, "pthread_create"); 130 131 start = time(NULL); 132 while (time(NULL) - start < 120) 133 func(); 134} 135EOF 136 137mycc -o /tmp/mvillard_nest -Wall -Wextra -O2 -g /tmp/mvillard_nest.c \ 138 -l pthread || exit 1 139rm /tmp/mvillard_nest.c 140 141/tmp/mvillard_nest; s=$? 142 143rm /tmp/mvillard_nest 144exit $s 145