linux32_machdep.c (167157) | linux32_machdep.c (168035) |
---|---|
1/*- 2 * Copyright (c) 2004 Tim J. Robbins 3 * Copyright (c) 2002 Doug Rabson 4 * Copyright (c) 2000 Marcel Moolenaar 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 --- 15 unchanged lines hidden (view full) --- 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2004 Tim J. Robbins 3 * Copyright (c) 2002 Doug Rabson 4 * Copyright (c) 2000 Marcel Moolenaar 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 --- 15 unchanged lines hidden (view full) --- 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include <sys/cdefs.h> |
32__FBSDID("$FreeBSD: head/sys/amd64/linux32/linux32_machdep.c 167157 2007-03-02 00:08:47Z jkim $"); | 32__FBSDID("$FreeBSD: head/sys/amd64/linux32/linux32_machdep.c 168035 2007-03-30 00:06:21Z jkim $"); |
33 34#include <sys/param.h> 35#include <sys/kernel.h> 36#include <sys/systm.h> 37#include <sys/file.h> 38#include <sys/fcntl.h> 39#include <sys/clock.h> 40#include <sys/imgact.h> --- 7 unchanged lines hidden (view full) --- 48#include <sys/resource.h> 49#include <sys/resourcevar.h> 50#include <sys/sched.h> 51#include <sys/syscallsubr.h> 52#include <sys/sysproto.h> 53#include <sys/unistd.h> 54 55#include <machine/frame.h> | 33 34#include <sys/param.h> 35#include <sys/kernel.h> 36#include <sys/systm.h> 37#include <sys/file.h> 38#include <sys/fcntl.h> 39#include <sys/clock.h> 40#include <sys/imgact.h> --- 7 unchanged lines hidden (view full) --- 48#include <sys/resource.h> 49#include <sys/resourcevar.h> 50#include <sys/sched.h> 51#include <sys/syscallsubr.h> 52#include <sys/sysproto.h> 53#include <sys/unistd.h> 54 55#include <machine/frame.h> |
56#include <machine/pcb.h> |
|
56#include <machine/psl.h> | 57#include <machine/psl.h> |
58#include <machine/segments.h> 59#include <machine/specialreg.h> |
|
57 58#include <vm/vm.h> 59#include <vm/pmap.h> 60#include <vm/vm_extern.h> 61#include <vm/vm_kern.h> 62#include <vm/vm_map.h> 63 64#include <amd64/linux32/linux.h> --- 586 unchanged lines hidden (view full) --- 651 /* 652 * in a case of stack = NULL we are supposed to COW calling process stack 653 * this is what normal fork() does so we just keep the tf_rsp arg intact 654 */ 655 if (args->stack) 656 td2->td_frame->tf_rsp = PTROUT(args->stack); 657 658 if (args->flags & LINUX_CLONE_SETTLS) { | 60 61#include <vm/vm.h> 62#include <vm/pmap.h> 63#include <vm/vm_extern.h> 64#include <vm/vm_kern.h> 65#include <vm/vm_map.h> 66 67#include <amd64/linux32/linux.h> --- 586 unchanged lines hidden (view full) --- 654 /* 655 * in a case of stack = NULL we are supposed to COW calling process stack 656 * this is what normal fork() does so we just keep the tf_rsp arg intact 657 */ 658 if (args->stack) 659 td2->td_frame->tf_rsp = PTROUT(args->stack); 660 661 if (args->flags & LINUX_CLONE_SETTLS) { |
659 /* XXX: todo */ | 662 struct user_segment_descriptor sd; 663 struct l_user_desc info; 664 int a[2]; 665 666 error = copyin((void *)td->td_frame->tf_rsi, &info, 667 sizeof(struct l_user_desc)); 668 if (error) { 669 printf(LMSG("copyin failed!")); 670 } else { 671 /* We might copy out the entry_number as GUGS32_SEL. */ 672 info.entry_number = GUGS32_SEL; 673 error = copyout(&info, (void *)td->td_frame->tf_rsi, 674 sizeof(struct l_user_desc)); 675 if (error) 676 printf(LMSG("copyout failed!")); 677 678 a[0] = LINUX_LDT_entry_a(&info); 679 a[1] = LINUX_LDT_entry_b(&info); 680 681 memcpy(&sd, &a, sizeof(a)); 682#ifdef DEBUG 683 if (ldebug(clone)) 684 printf("Segment created in clone with " 685 "CLONE_SETTLS: lobase: %x, hibase: %x, " 686 "lolimit: %x, hilimit: %x, type: %i, " 687 "dpl: %i, p: %i, xx: %i, long: %i, " 688 "def32: %i, gran: %i\n", sd.sd_lobase, 689 sd.sd_hibase, sd.sd_lolimit, sd.sd_hilimit, 690 sd.sd_type, sd.sd_dpl, sd.sd_p, sd.sd_xx, 691 sd.sd_long, sd.sd_def32, sd.sd_gran); 692#endif 693 td2->td_pcb->pcb_gsbase = (register_t)info.base_addr; 694 td2->td_pcb->pcb_gs32sd = sd; 695 td2->td_pcb->pcb_gs32p = &gdt[GUGS32_SEL]; 696 td2->td_pcb->pcb_gs = GSEL(GUGS32_SEL, SEL_UPL); 697 td2->td_pcb->pcb_flags |= PCB_32BIT; 698 } |
660 } 661 662#ifdef DEBUG 663 if (ldebug(clone)) 664 printf(LMSG("clone: successful rfork to %ld, stack %p sig = %d"), 665 (long)p2->p_pid, args->stack, exit_signal); 666#endif 667 if (args->flags & LINUX_CLONE_VFORK) { --- 232 unchanged lines hidden (view full) --- 900 if (ldebug(mmap)) 901 printf("-> %s() return: 0x%x (0x%08x)\n", 902 __func__, error, (u_int)td->td_retval[0]); 903#endif 904 return (error); 905} 906 907int | 699 } 700 701#ifdef DEBUG 702 if (ldebug(clone)) 703 printf(LMSG("clone: successful rfork to %ld, stack %p sig = %d"), 704 (long)p2->p_pid, args->stack, exit_signal); 705#endif 706 if (args->flags & LINUX_CLONE_VFORK) { --- 232 unchanged lines hidden (view full) --- 939 if (ldebug(mmap)) 940 printf("-> %s() return: 0x%x (0x%08x)\n", 941 __func__, error, (u_int)td->td_retval[0]); 942#endif 943 return (error); 944} 945 946int |
947linux_mprotect(struct thread *td, struct linux_mprotect_args *uap) 948{ 949 struct mprotect_args bsd_args; 950 951 bsd_args.addr = uap->addr; 952 bsd_args.len = uap->len; 953 bsd_args.prot = uap->prot; 954 if (bsd_args.prot & (PROT_READ | PROT_WRITE | PROT_EXEC)) 955 bsd_args.prot |= PROT_READ | PROT_EXEC; 956 return (mprotect(td, &bsd_args)); 957} 958 959int |
|
908linux_iopl(struct thread *td, struct linux_iopl_args *args) 909{ 910 int error; 911 912 if (args->level < 0 || args->level > 3) 913 return (EINVAL); 914 if ((error = priv_check(td, PRIV_IO)) != 0) 915 return (error); --- 256 unchanged lines hidden (view full) --- 1172 if (error != 0) 1173 return (error); 1174 ts32.tv_sec = ts.tv_sec; 1175 ts32.tv_nsec = ts.tv_nsec; 1176 return (copyout(&ts32, uap->interval, sizeof(ts32))); 1177} 1178 1179int | 960linux_iopl(struct thread *td, struct linux_iopl_args *args) 961{ 962 int error; 963 964 if (args->level < 0 || args->level > 3) 965 return (EINVAL); 966 if ((error = priv_check(td, PRIV_IO)) != 0) 967 return (error); --- 256 unchanged lines hidden (view full) --- 1224 if (error != 0) 1225 return (error); 1226 ts32.tv_sec = ts.tv_sec; 1227 ts32.tv_nsec = ts.tv_nsec; 1228 return (copyout(&ts32, uap->interval, sizeof(ts32))); 1229} 1230 1231int |
1180linux_mprotect(struct thread *td, struct linux_mprotect_args *uap) | 1232linux_set_thread_area(struct thread *td, 1233 struct linux_set_thread_area_args *args) |
1181{ | 1234{ |
1182 struct mprotect_args bsd_args; | 1235 struct l_user_desc info; 1236 struct user_segment_descriptor sd; 1237 int a[2]; 1238 int error; |
1183 | 1239 |
1184 bsd_args.addr = uap->addr; 1185 bsd_args.len = uap->len; 1186 bsd_args.prot = uap->prot; 1187 if (bsd_args.prot & (PROT_READ | PROT_WRITE | PROT_EXEC)) 1188 bsd_args.prot |= PROT_READ | PROT_EXEC; 1189 return (mprotect(td, &bsd_args)); | 1240 error = copyin(args->desc, &info, sizeof(struct l_user_desc)); 1241 if (error) 1242 return (error); 1243 1244#ifdef DEBUG 1245 if (ldebug(set_thread_area)) 1246 printf(ARGS(set_thread_area, "%i, %x, %x, %i, %i, %i, " 1247 "%i, %i, %i"), info.entry_number, info.base_addr, 1248 info.limit, info.seg_32bit, info.contents, 1249 info.read_exec_only, info.limit_in_pages, 1250 info.seg_not_present, info.useable); 1251#endif 1252 1253 /* 1254 * Semantics of Linux version: every thread in the system has array 1255 * of three TLS descriptors. 1st is GLIBC TLS, 2nd is WINE, 3rd unknown. 1256 * This syscall loads one of the selected TLS decriptors with a value 1257 * and also loads GDT descriptors 6, 7 and 8 with the content of 1258 * the per-thread descriptors. 1259 * 1260 * Semantics of FreeBSD version: I think we can ignore that Linux has 1261 * three per-thread descriptors and use just the first one. 1262 * The tls_array[] is used only in [gs]et_thread_area() syscalls and 1263 * for loading the GDT descriptors. We use just one GDT descriptor 1264 * for TLS, so we will load just one. 1265 * XXX: This doesnt work when user-space process tries to use more 1266 * than one TLS segment. Comment in the Linux source says wine might 1267 * do that. 1268 */ 1269 1270 /* 1271 * GLIBC reads current %gs and call set_thread_area() with it. 1272 * We should let GUDATA_SEL and GUGS32_SEL proceed as well because 1273 * we use these segments. 1274 */ 1275 switch (info.entry_number) { 1276 case GUGS32_SEL: 1277 case GUDATA_SEL: 1278 case 6: 1279 case -1: 1280 info.entry_number = GUGS32_SEL; 1281 break; 1282 default: 1283 return (EINVAL); 1284 } 1285 1286 /* 1287 * We have to copy out the GDT entry we use. 1288 * XXX: What if userspace program does not check return value and 1289 * tries to use 6, 7 or 8? 1290 */ 1291 error = copyout(&info, args->desc, sizeof(struct l_user_desc)); 1292 if (error) 1293 return (error); 1294 1295 if (LINUX_LDT_empty(&info)) { 1296 a[0] = 0; 1297 a[1] = 0; 1298 } else { 1299 a[0] = LINUX_LDT_entry_a(&info); 1300 a[1] = LINUX_LDT_entry_b(&info); 1301 } 1302 1303 memcpy(&sd, &a, sizeof(a)); 1304#ifdef DEBUG 1305 if (ldebug(set_thread_area)) 1306 printf("Segment created in set_thread_area: " 1307 "lobase: %x, hibase: %x, lolimit: %x, hilimit: %x, " 1308 "type: %i, dpl: %i, p: %i, xx: %i, long: %i, " 1309 "def32: %i, gran: %i\n", 1310 sd.sd_lobase, 1311 sd.sd_hibase, 1312 sd.sd_lolimit, 1313 sd.sd_hilimit, 1314 sd.sd_type, 1315 sd.sd_dpl, 1316 sd.sd_p, 1317 sd.sd_xx, 1318 sd.sd_long, 1319 sd.sd_def32, 1320 sd.sd_gran); 1321#endif 1322 1323 critical_enter(); 1324 td->td_pcb->pcb_gsbase = (register_t)info.base_addr; 1325 td->td_pcb->pcb_gs32sd = gdt[GUGS32_SEL] = sd; 1326 td->td_pcb->pcb_gs32p = &gdt[GUGS32_SEL]; 1327 td->td_pcb->pcb_flags |= PCB_32BIT; 1328 wrmsr(MSR_KGSBASE, td->td_pcb->pcb_gsbase); 1329 critical_exit(); 1330 1331 return (0); |
1190} | 1332} |