Date: Fri, 30 Mar 2007 18:25:57 GMT From: Marcel Moolenaar <marcel@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 116949 for review Message-ID: <200703301825.l2UIPvIU063960@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=116949 Change 116949 by marcel@marcel_xcllnt on 2007/03/30 18:25:41 IFC @116947 Affected files ... .. //depot/projects/uart/amd64/amd64/cpu_switch.S#5 integrate .. //depot/projects/uart/amd64/amd64/genassym.c#10 integrate .. //depot/projects/uart/amd64/amd64/machdep.c#26 integrate .. //depot/projects/uart/amd64/amd64/support.S#9 integrate .. //depot/projects/uart/amd64/include/pcb.h#4 integrate .. //depot/projects/uart/amd64/include/segments.h#4 integrate .. //depot/projects/uart/amd64/linux32/linux.h#6 integrate .. //depot/projects/uart/amd64/linux32/linux32_dummy.c#7 integrate .. //depot/projects/uart/amd64/linux32/linux32_locore.s#2 integrate .. //depot/projects/uart/amd64/linux32/linux32_machdep.c#10 integrate .. //depot/projects/uart/amd64/linux32/linux32_proto.h#13 integrate .. //depot/projects/uart/amd64/linux32/linux32_syscall.h#13 integrate .. //depot/projects/uart/amd64/linux32/linux32_sysent.c#13 integrate .. //depot/projects/uart/amd64/linux32/linux32_sysvec.c#14 integrate .. //depot/projects/uart/amd64/linux32/syscalls.master#13 integrate .. //depot/projects/uart/boot/arm/at91/libat91/at91rm9200_lowlevel.c#4 integrate .. //depot/projects/uart/boot/arm/at91/libat91/at91rm9200_lowlevel.h#5 integrate .. //depot/projects/uart/boot/arm/at91/libat91/emac.c#5 integrate .. //depot/projects/uart/boot/arm/at91/libat91/getc.c#3 integrate .. //depot/projects/uart/boot/arm/at91/libat91/sd-card.c#3 integrate .. //depot/projects/uart/boot/arm/at91/libat91/spi_flash.c#4 integrate .. //depot/projects/uart/compat/linprocfs/linprocfs.c#23 integrate .. //depot/projects/uart/compat/linux/linux_file.c#12 integrate .. //depot/projects/uart/compat/linux/linux_futex.c#3 integrate .. //depot/projects/uart/compat/linux/linux_util.h#8 integrate .. //depot/projects/uart/dev/acpica/acpi_hpet.c#4 integrate .. //depot/projects/uart/dev/firewire/firewire.c#13 integrate .. //depot/projects/uart/dev/isp/isp.c#20 integrate .. //depot/projects/uart/dev/sio/sio_pci.c#8 integrate .. //depot/projects/uart/geom/geom_ctl.c#10 integrate .. //depot/projects/uart/i386/i386/support.s#9 integrate .. //depot/projects/uart/i386/linux/linux.h#8 integrate .. //depot/projects/uart/i386/linux/linux_dummy.c#9 integrate .. //depot/projects/uart/i386/linux/linux_proto.h#15 integrate .. //depot/projects/uart/i386/linux/linux_syscall.h#15 integrate .. //depot/projects/uart/i386/linux/linux_sysent.c#15 integrate .. //depot/projects/uart/i386/linux/syscalls.master#15 integrate .. //depot/projects/uart/kern/kern_lock.c#17 integrate .. //depot/projects/uart/kern/kern_rwlock.c#10 integrate .. //depot/projects/uart/kern/vfs_bio.c#29 integrate .. //depot/projects/uart/netgraph/bluetooth/l2cap/ng_l2cap_cmds.c#6 integrate .. //depot/projects/uart/netgraph/ng_base.c#16 integrate .. //depot/projects/uart/netinet/in.c#14 integrate .. //depot/projects/uart/sys/lockmgr.h#10 integrate .. //depot/projects/uart/sys/mount.h#21 integrate .. //depot/projects/uart/sys/mutex.h#17 integrate .. //depot/projects/uart/ufs/ffs/ffs_softdep.c#24 integrate Differences ... ==== //depot/projects/uart/amd64/amd64/cpu_switch.S#5 (text+ko) ==== @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/amd64/amd64/cpu_switch.S,v 1.155 2006/12/20 04:40:38 davidxu Exp $ + * $FreeBSD: src/sys/amd64/amd64/cpu_switch.S,v 1.156 2007/03/30 00:06:20 jkim Exp $ */ #include <machine/asmacros.h> @@ -104,11 +104,12 @@ testl $PCB_32BIT,PCB_FLAGS(%r8) jz 1f /* no, skip over */ - /* Save segment selector numbers */ - movl %ds,PCB_DS(%r8) - movl %es,PCB_ES(%r8) - movl %fs,PCB_FS(%r8) + /* Save userland %gs */ movl %gs,PCB_GS(%r8) + movq PCB_GS32P(%r8),%rax + movq (%rax),%rax + movq %rax,PCB_GS32SD(%r8) + 1: /* Test if debug registers should be saved. */ testl $PCB_DBREGS,PCB_FLAGS(%r8) @@ -170,22 +171,6 @@ */ movq TD_PCB(%rsi),%r8 - testl $PCB_32BIT,PCB_FLAGS(%r8) - jz 1f /* no, skip over */ - - /* Restore segment selector numbers */ - movl PCB_DS(%r8),%ds - movl PCB_ES(%r8),%es - movl PCB_FS(%r8),%fs - - /* Restore userland %gs while preserving kernel gsbase */ - movl $MSR_GSBASE,%ecx - rdmsr - movl PCB_GS(%r8),%gs - wrmsr - jmp 2f -1: - /* Restore userland %fs */ movl $MSR_FSBASE,%ecx movl PCB_FSBASE(%r8),%eax @@ -197,7 +182,6 @@ movl PCB_GSBASE(%r8),%eax movl PCB_GSBASE+4(%r8),%edx wrmsr -2: /* Update the TSS_RSP0 pointer for the next interrupt */ movq PCPU(TSSP), %rax @@ -211,6 +195,19 @@ movl %eax, PCPU(CURTID) movq %rsi, PCPU(CURTHREAD) /* into next thread */ + testl $PCB_32BIT,PCB_FLAGS(%r8) + jz 1f /* no, skip over */ + + /* Restore userland %gs while preserving kernel gsbase */ + movq PCB_GS32P(%r8),%rax + movq PCB_GS32SD(%r8),%rbx + movq %rbx,(%rax) + movl $MSR_GSBASE,%ecx + rdmsr + movl PCB_GS(%r8),%gs + wrmsr + +1: /* Restore context. */ movq PCB_RBX(%r8),%rbx movq PCB_RSP(%r8),%rsp ==== //depot/projects/uart/amd64/amd64/genassym.c#10 (text+ko) ==== @@ -33,7 +33,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/amd64/amd64/genassym.c,v 1.160 2006/12/20 04:40:38 davidxu Exp $"); +__FBSDID("$FreeBSD: src/sys/amd64/amd64/genassym.c,v 1.161 2007/03/30 00:06:20 jkim Exp $"); #include "opt_compat.h" #include "opt_kstack_pages.h" @@ -136,12 +136,14 @@ ASSYM(PCB_DR7, offsetof(struct pcb, pcb_dr7)); ASSYM(PCB_DBREGS, PCB_DBREGS); ASSYM(PCB_32BIT, PCB_32BIT); +ASSYM(PCB_FULLCTX, PCB_FULLCTX); ASSYM(PCB_FLAGS, offsetof(struct pcb, pcb_flags)); -ASSYM(PCB_FULLCTX, PCB_FULLCTX); ASSYM(PCB_SAVEFPU, offsetof(struct pcb, pcb_save)); ASSYM(PCB_SAVEFPU_SIZE, sizeof(struct savefpu)); ASSYM(PCB_ONFAULT, offsetof(struct pcb, pcb_onfault)); +ASSYM(PCB_GS32P, offsetof(struct pcb, pcb_gs32p)); +ASSYM(PCB_GS32SD, offsetof(struct pcb, pcb_gs32sd)); ASSYM(PCB_SIZE, sizeof(struct pcb)); ==== //depot/projects/uart/amd64/amd64/machdep.c#26 (text+ko) ==== @@ -39,7 +39,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/amd64/amd64/machdep.c,v 1.669 2007/01/27 18:13:24 jkoshy Exp $"); +__FBSDID("$FreeBSD: src/sys/amd64/amd64/machdep.c,v 1.670 2007/03/30 00:06:20 jkim Exp $"); #include "opt_atalk.h" #include "opt_atpic.h" @@ -725,6 +725,15 @@ 0, /* long */ 0, /* default 32 vs 16 bit size */ 0 /* limit granularity (byte/page units)*/ }, +/* GUGS32_SEL 8 32 bit GS Descriptor for user */ +{ 0x0, /* segment base address */ + 0xfffff, /* length - all address space */ + SDT_MEMRWA, /* segment type */ + SEL_UPL, /* segment descriptor priority level */ + 1, /* segment descriptor present */ + 0, /* long */ + 1, /* default 32 vs 16 bit size */ + 1 /* limit granularity (byte/page units)*/ }, }; void ==== //depot/projects/uart/amd64/amd64/support.S#9 (text+ko) ==== @@ -27,7 +27,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/amd64/amd64/support.S,v 1.121 2006/10/17 02:24:45 davidxu Exp $ + * $FreeBSD: src/sys/amd64/amd64/support.S,v 1.122 2007/03/30 01:07:27 jkim Exp $ */ #include "opt_ddb.h" @@ -689,3 +689,47 @@ movq %rax,32(%rdi) movq %rdi,bbhead NON_GPROF_RET + +#if defined(SMP) || !defined(_KERNEL) +#define MPLOCKED lock ; +#else +#define MPLOCKED +#endif + + .text + +futex_fault: + movq PCPU(CURPCB), %rdx + movq $0, PCB_ONFAULT(%rdx) + movq $-EFAULT, %rax + ret + +/* int futex_xchgl(int oparg, caddr_t uaddr, int *oldval); */ +ENTRY(futex_xchgl) + movq PCPU(CURPCB), %r11 + movq $futex_fault, PCB_ONFAULT(%r11) + + movq $VM_MAXUSER_ADDRESS-4, %rax + cmpq %rax, %rsi + ja futex_fault + + MPLOCKED xchgl %edi, (%rsi) + movl %edi, (%rdx) + xorl %eax, %eax + movq %rax, PCB_ONFAULT(%r11) + ret + +/* int futex_addl(int oparg, caddr_t uaddr, int *oldval); */ +ENTRY(futex_addl) + movq PCPU(CURPCB), %r11 + movq $futex_fault, PCB_ONFAULT(%r11) + + movq $VM_MAXUSER_ADDRESS-4, %rax + cmpq %rax, %rsi + ja futex_fault + + MPLOCKED xaddl %edi, (%rsi) + movl %edi, (%rdx) + xorl %eax, %eax + movq %rax, PCB_ONFAULT(%r11) + ret ==== //depot/projects/uart/amd64/include/pcb.h#4 (text+ko) ==== @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)pcb.h 5.10 (Berkeley) 5/12/91 - * $FreeBSD: src/sys/amd64/include/pcb.h,v 1.62 2005/09/27 21:11:35 peter Exp $ + * $FreeBSD: src/sys/amd64/include/pcb.h,v 1.63 2007/03/30 00:06:21 jkim Exp $ */ #ifndef _AMD64_PCB_H_ @@ -41,6 +41,7 @@ * AMD64 process control block */ #include <machine/fpu.h> +#include <machine/segments.h> struct pcb { register_t pcb_cr3; @@ -73,6 +74,10 @@ #define PCB_FULLCTX 0x80 /* full context restore on sysret */ caddr_t pcb_onfault; /* copyin/out fault recovery */ + + /* 32-bit segment descriptor */ + struct user_segment_descriptor *pcb_gs32p; + struct user_segment_descriptor pcb_gs32sd; }; #ifdef _KERNEL ==== //depot/projects/uart/amd64/include/segments.h#4 (text+ko) ==== @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)segments.h 7.1 (Berkeley) 5/9/91 - * $FreeBSD: src/sys/amd64/include/segments.h,v 1.38 2004/04/05 21:25:51 imp Exp $ + * $FreeBSD: src/sys/amd64/include/segments.h,v 1.39 2007/03/30 00:06:21 jkim Exp $ */ #ifndef _MACHINE_SEGMENTS_H_ @@ -200,9 +200,10 @@ #define GUCODE32_SEL 3 /* User 32 bit code Descriptor */ #define GUDATA_SEL 4 /* User 32/64 bit Data Descriptor */ #define GUCODE_SEL 5 /* User 64 bit Code Descriptor */ -#define GPROC0_SEL 6 /* TSS for entering kernel etc */ +#define GPROC0_SEL 6 /* TSS for entering kernel etc */ /* slot 6 is second half of GPROC0_SEL */ -#define NGDT 8 +#define GUGS32_SEL 8 /* User 32 bit GS Descriptor */ +#define NGDT 9 #ifdef _KERNEL extern struct user_segment_descriptor gdt[]; ==== //depot/projects/uart/amd64/linux32/linux.h#6 (text+ko) ==== @@ -27,7 +27,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/amd64/linux32/linux.h,v 1.14 2007/03/02 00:08:47 jkim Exp $ + * $FreeBSD: src/sys/amd64/linux32/linux.h,v 1.15 2007/03/29 02:11:46 julian Exp $ */ #ifndef _AMD64_LINUX_H_ @@ -531,6 +531,7 @@ #define LINUX_O_RDONLY 00000000 #define LINUX_O_WRONLY 00000001 #define LINUX_O_RDWR 00000002 +#define LINUX_O_ACCMODE 00000003 #define LINUX_O_CREAT 00000100 #define LINUX_O_EXCL 00000200 #define LINUX_O_NOCTTY 00000400 @@ -565,6 +566,8 @@ #define LINUX_F_WRLCK 1 #define LINUX_F_UNLCK 2 +#define LINUX_AT_FDCWD -100 + /* * mount flags */ ==== //depot/projects/uart/amd64/linux32/linux32_dummy.c#7 (text+ko) ==== @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/amd64/linux32/linux32_dummy.c,v 1.7 2006/12/31 13:16:00 netchild Exp $"); +__FBSDID("$FreeBSD: src/sys/amd64/linux32/linux32_dummy.c,v 1.8 2007/03/29 02:11:46 julian Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -97,7 +97,6 @@ DUMMY(inotify_add_watch); DUMMY(inotify_rm_watch); DUMMY(migrate_pages); -DUMMY(openat); DUMMY(mkdirat); DUMMY(mknodat); DUMMY(fchownat); ==== //depot/projects/uart/amd64/linux32/linux32_locore.s#2 (text+ko) ==== @@ -1,4 +1,4 @@ -/* $FreeBSD: src/sys/amd64/linux32/linux32_locore.s,v 1.1 2004/08/16 07:55:06 tjr Exp $ */ +/* $FreeBSD: src/sys/amd64/linux32/linux32_locore.s,v 1.2 2007/03/30 00:06:21 jkim Exp $ */ #include "linux32_assym.h" /* system definitions */ #include <machine/asmacros.h> /* miscellaneous asm macros */ @@ -11,8 +11,6 @@ NON_GPROF_ENTRY(linux_sigcode) call *LINUX_SIGF_HANDLER(%esp) leal LINUX_SIGF_SC(%esp),%ebx /* linux scp */ - movl LINUX_SC_GS(%ebx),%gs - movl LINUX_SC_FS(%ebx),%fs movl LINUX_SC_ES(%ebx),%es movl LINUX_SC_DS(%ebx),%ds movl %esp, %ebx /* pass sigframe */ @@ -25,8 +23,6 @@ linux_rt_sigcode: call *LINUX_RT_SIGF_HANDLER(%esp) leal LINUX_RT_SIGF_UC(%esp),%ebx /* linux ucp */ - movl LINUX_SC_GS(%ebx),%gs - movl LINUX_SC_FS(%ebx),%fs movl LINUX_SC_ES(%ebx),%es movl LINUX_SC_DS(%ebx),%ds push %eax /* fake ret addr */ ==== //depot/projects/uart/amd64/linux32/linux32_machdep.c#10 (text+ko) ==== @@ -29,7 +29,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/amd64/linux32/linux32_machdep.c,v 1.36 2007/03/02 00:08:47 jkim Exp $"); +__FBSDID("$FreeBSD: src/sys/amd64/linux32/linux32_machdep.c,v 1.39 2007/03/30 17:27:13 jkim Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -53,7 +53,10 @@ #include <sys/unistd.h> #include <machine/frame.h> +#include <machine/pcb.h> #include <machine/psl.h> +#include <machine/segments.h> +#include <machine/specialreg.h> #include <vm/vm.h> #include <vm/pmap.h> @@ -121,7 +124,7 @@ * Allocate temporary demand zeroed space for argument and * environment strings */ - args->buf = (char *) kmem_alloc_wait(exec_map, + args->buf = (char *)kmem_alloc_wait(exec_map, PATH_MAX + ARG_MAX + MAXSHELLCMDLEN); if (args->buf == NULL) return (ENOMEM); @@ -155,14 +158,14 @@ if (error) { if (error == ENAMETOOLONG) error = E2BIG; - + goto err_exit; } args->stringspace -= length; args->endp += length; args->argc++; } - + args->begin_envv = args->endp; /* @@ -219,13 +222,13 @@ if (error == 0) error = kern_execve(td, &eargs, NULL); if (error == 0) - /* linux process can exec fbsd one, dont attempt + /* Linux process can execute FreeBSD one, do not attempt * to create emuldata for such process using * linux_proc_init, this leads to a panic on KASSERT - * because such process has p->p_emuldata == NULL + * because such process has p->p_emuldata == NULL. */ if (td->td_proc->p_sysent == &elf_linux_sysvec) - error = linux_proc_init(td, 0, 0); + error = linux_proc_init(td, 0, 0); return (error); } @@ -466,7 +469,7 @@ if ((error = fork1(td, RFFDG | RFPROC | RFSTOPPED, 0, &p2)) != 0) return (error); - + if (error == 0) { td->td_retval[0] = p2->p_pid; td->td_retval[1] = 0; @@ -480,7 +483,9 @@ td2 = FIRST_THREAD_IN_PROC(p2); - /* make it run */ + /* + * Make this runnable after we are finished with it. + */ mtx_lock_spin(&sched_lock); TD_SET_CAN_RUN(td2); sched_add(td2, SRQ_BORING); @@ -501,7 +506,7 @@ printf(ARGS(vfork, "")); #endif - /* exclude RFPPWAIT */ + /* Exclude RFPPWAIT */ if ((error = fork1(td, RFFDG | RFPROC | RFMEM | RFSTOPPED, 0, &p2)) != 0) return (error); if (error == 0) { @@ -520,7 +525,7 @@ PROC_UNLOCK(p2); td2 = FIRST_THREAD_IN_PROC(p2); - + /* make it run */ mtx_lock_spin(&sched_lock); TD_SET_CAN_RUN(td2); @@ -532,7 +537,7 @@ while (p2->p_flag & P_PPWAIT) msleep(td->td_proc, &p2->p_mtx, PWAIT, "ppwait", 0); PROC_UNLOCK(p2); - + return (0); } @@ -547,10 +552,9 @@ #ifdef DEBUG if (ldebug(clone)) { - printf(ARGS(clone, "flags %x, stack %x, parent tid: %x, child tid: %x"), - (unsigned int)args->flags, (unsigned int)(uintptr_t)args->stack, - (unsigned int)(uintptr_t)args->parent_tidptr, - (unsigned int)(uintptr_t)args->child_tidptr); + printf(ARGS(clone, "flags %x, stack %p, parent tid: %p, " + "child tid: %p"), (unsigned)args->flags, + args->stack, args->parent_tidptr, args->child_tidptr); } #endif @@ -565,11 +569,11 @@ ff |= RFMEM; if (args->flags & LINUX_CLONE_SIGHAND) ff |= RFSIGSHARE; - /* - * XXX: in linux sharing of fs info (chroot/cwd/umask) - * and open files is independant. in fbsd its in one - * structure but in reality it doesn't cause any problems - * because both of these flags are usually set together. + /* + * XXX: In Linux, sharing of fs info (chroot/cwd/umask) + * and open files is independant. In FreeBSD, its in one + * structure but in reality it does not make any problems + * because both of these flags are set at once usually. */ if (!(args->flags & (LINUX_CLONE_FILES | LINUX_CLONE_FS))) ff |= RFFDG; @@ -590,6 +594,10 @@ if ((args->flags & 0xffffff00) == LINUX_THREADING_FLAGS) ff |= RFTHREAD; + if (args->flags & LINUX_CLONE_PARENT_SETTID) + if (args->parent_tidptr == NULL) + return (EINVAL); + error = fork1(td, ff, 0, &p2); if (error) return (error); @@ -601,35 +609,21 @@ PROC_UNLOCK(p2); sx_xunlock(&proctree_lock); } - + /* create the emuldata */ error = linux_proc_init(td, p2->p_pid, args->flags); /* reference it - no need to check this */ em = em_find(p2, EMUL_DOLOCK); KASSERT(em != NULL, ("clone: emuldata not found.\n")); /* and adjust it */ - if (args->flags & LINUX_CLONE_PARENT_SETTID) { - if (args->parent_tidptr == NULL) { - EMUL_UNLOCK(&emul_lock); - return (EINVAL); - } - error = copyout(&p2->p_pid, args->parent_tidptr, sizeof(p2->p_pid)); - if (error) { - EMUL_UNLOCK(&emul_lock); - return (error); - } - } if (args->flags & LINUX_CLONE_THREAD) { - /* XXX: linux mangles pgrp and pptr somehow - * I think it might be this but I am not sure. - */ #ifdef notyet PROC_LOCK(p2); p2->p_pgrp = td->td_proc->p_pgrp; PROC_UNLOCK(p2); #endif - exit_signal = 0; + exit_signal = 0; } if (args->flags & LINUX_CLONE_CHILD_SETTID) @@ -644,25 +638,70 @@ EMUL_UNLOCK(&emul_lock); + if (args->flags & LINUX_CLONE_PARENT_SETTID) { + error = copyout(&p2->p_pid, args->parent_tidptr, + sizeof(p2->p_pid)); + if (error) + printf(LMSG("copyout failed!")); + } + PROC_LOCK(p2); p2->p_sigparent = exit_signal; PROC_UNLOCK(p2); td2 = FIRST_THREAD_IN_PROC(p2); - /* - * in a case of stack = NULL we are supposed to COW calling process stack - * this is what normal fork() does so we just keep the tf_rsp arg intact + /* + * In a case of stack = NULL, we are supposed to COW calling process + * stack. This is what normal fork() does, so we just keep tf_rsp arg + * intact. */ if (args->stack) - td2->td_frame->tf_rsp = PTROUT(args->stack); + td2->td_frame->tf_rsp = PTROUT(args->stack); if (args->flags & LINUX_CLONE_SETTLS) { - /* XXX: todo */ + struct user_segment_descriptor sd; + struct l_user_desc info; + int a[2]; + + error = copyin((void *)td->td_frame->tf_rsi, &info, + sizeof(struct l_user_desc)); + if (error) { + printf(LMSG("copyin failed!")); + } else { + /* We might copy out the entry_number as GUGS32_SEL. */ + info.entry_number = GUGS32_SEL; + error = copyout(&info, (void *)td->td_frame->tf_rsi, + sizeof(struct l_user_desc)); + if (error) + printf(LMSG("copyout failed!")); + + a[0] = LINUX_LDT_entry_a(&info); + a[1] = LINUX_LDT_entry_b(&info); + + memcpy(&sd, &a, sizeof(a)); +#ifdef DEBUG + if (ldebug(clone)) + printf("Segment created in clone with " + "CLONE_SETTLS: lobase: %x, hibase: %x, " + "lolimit: %x, hilimit: %x, type: %i, " + "dpl: %i, p: %i, xx: %i, long: %i, " + "def32: %i, gran: %i\n", sd.sd_lobase, + sd.sd_hibase, sd.sd_lolimit, sd.sd_hilimit, + sd.sd_type, sd.sd_dpl, sd.sd_p, sd.sd_xx, + sd.sd_long, sd.sd_def32, sd.sd_gran); +#endif + td2->td_pcb->pcb_gsbase = (register_t)info.base_addr; + td2->td_pcb->pcb_gs32sd = sd; + td2->td_pcb->pcb_gs32p = &gdt[GUGS32_SEL]; + td2->td_pcb->pcb_gs = GSEL(GUGS32_SEL, SEL_UPL); + td2->td_pcb->pcb_flags |= PCB_32BIT; + } } #ifdef DEBUG if (ldebug(clone)) - printf(LMSG("clone: successful rfork to %ld, stack %p sig = %d"), - (long)p2->p_pid, args->stack, exit_signal); + printf(LMSG("clone: successful rfork to %d, " + "stack %p sig = %d"), (int)p2->p_pid, args->stack, + exit_signal); #endif if (args->flags & LINUX_CLONE_VFORK) { PROC_LOCK(p2); @@ -680,12 +719,12 @@ td->td_retval[0] = p2->p_pid; td->td_retval[1] = 0; - + if (args->flags & LINUX_CLONE_VFORK) { - /* wait for the children to exit, ie. emulate vfork */ - PROC_LOCK(p2); + /* wait for the children to exit, ie. emulate vfork */ + PROC_LOCK(p2); while (p2->p_flag & P_PPWAIT) - msleep(td->td_proc, &p2->p_mtx, PWAIT, "ppwait", 0); + msleep(td->td_proc, &p2->p_mtx, PWAIT, "ppwait", 0); PROC_UNLOCK(p2); } @@ -704,8 +743,8 @@ #ifdef DEBUG if (ldebug(mmap2)) - printf(ARGS(mmap2, "%p, %d, %d, 0x%08x, %d, %d"), - (void *)(intptr_t)args->addr, args->len, args->prot, + printf(ARGS(mmap2, "0x%08x, %d, %d, 0x%08x, %d, %d"), + args->addr, args->len, args->prot, args->flags, args->fd, args->pgoff); #endif @@ -731,10 +770,9 @@ #ifdef DEBUG if (ldebug(mmap)) - printf(ARGS(mmap, "%p, %d, %d, 0x%08x, %d, %d"), - (void *)(intptr_t)linux_args.addr, linux_args.len, - linux_args.prot, linux_args.flags, linux_args.fd, - linux_args.pgoff); + printf(ARGS(mmap, "0x%08x, %d, %d, 0x%08x, %d, %d"), + linux_args.addr, linux_args.len, linux_args.prot, + linux_args.flags, linux_args.fd, linux_args.pgoff); #endif if ((linux_args.pgoff % PAGE_SIZE) != 0) return (EINVAL); @@ -820,14 +858,14 @@ } if (linux_args->flags & LINUX_MAP_GROWSDOWN) { - /* - * The linux MAP_GROWSDOWN option does not limit auto + /* + * The Linux MAP_GROWSDOWN option does not limit auto * growth of the region. Linux mmap with this option * takes as addr the inital BOS, and as len, the initial * region size. It can then grow down from addr without - * limit. However, linux threads has an implicit internal + * limit. However, Linux threads has an implicit internal * limit to stack size of STACK_SIZE. Its just not - * enforced explicitly in linux. But, here we impose + * enforced explicitly in Linux. But, here we impose * a limit of (STACK_SIZE - GUARD_SIZE) on the stack * region, since we can do this with our mmap. * @@ -844,8 +882,8 @@ if ((caddr_t)PTRIN(linux_args->addr) + linux_args->len > p->p_vmspace->vm_maxsaddr) { - /* - * Some linux apps will attempt to mmap + /* + * Some Linux apps will attempt to mmap * thread stacks near the top of their * address space. If their TOS is greater * than vm_maxsaddr, vm_map_growstack() @@ -872,7 +910,7 @@ else bsd_args.len = STACK_SIZE - GUARD_SIZE; - /* + /* * This gives us a new BOS. If we're using VM_STACK, then * mmap will just map the top SGROWSIZ bytes, and let * the stack grow down to the limit at BOS. If we're @@ -905,6 +943,19 @@ } int +linux_mprotect(struct thread *td, struct linux_mprotect_args *uap) +{ + struct mprotect_args bsd_args; + + bsd_args.addr = uap->addr; + bsd_args.len = uap->len; + bsd_args.prot = uap->prot; + if (bsd_args.prot & (PROT_READ | PROT_WRITE | PROT_EXEC)) + bsd_args.prot |= PROT_READ | PROT_EXEC; + return (mprotect(td, &bsd_args)); +} + +int linux_iopl(struct thread *td, struct linux_iopl_args *args) { int error; @@ -992,7 +1043,7 @@ } /* - * Linux has two extra args, restart and oldmask. We dont use these, + * Linux has two extra args, restart and oldmask. We don't use these, * but it seems that "restart" is actually a context pointer that * enables the signal to happen with a different register set. */ @@ -1177,14 +1228,104 @@ } int -linux_mprotect(struct thread *td, struct linux_mprotect_args *uap) +linux_set_thread_area(struct thread *td, + struct linux_set_thread_area_args *args) { - struct mprotect_args bsd_args; + struct l_user_desc info; + struct user_segment_descriptor sd; + int a[2]; + int error; + + error = copyin(args->desc, &info, sizeof(struct l_user_desc)); + if (error) + return (error); + +#ifdef DEBUG + if (ldebug(set_thread_area)) + printf(ARGS(set_thread_area, "%i, %x, %x, %i, %i, %i, " + "%i, %i, %i"), info.entry_number, info.base_addr, + info.limit, info.seg_32bit, info.contents, + info.read_exec_only, info.limit_in_pages, + info.seg_not_present, info.useable); +#endif + + /* + * Semantics of Linux version: every thread in the system has array + * of three TLS descriptors. 1st is GLIBC TLS, 2nd is WINE, 3rd unknown. + * This syscall loads one of the selected TLS decriptors with a value + * and also loads GDT descriptors 6, 7 and 8 with the content of + * the per-thread descriptors. + * + * Semantics of FreeBSD version: I think we can ignore that Linux has + * three per-thread descriptors and use just the first one. + * The tls_array[] is used only in [gs]et_thread_area() syscalls and + * for loading the GDT descriptors. We use just one GDT descriptor + * for TLS, so we will load just one. + * XXX: This doesnt work when user-space process tries to use more + * than one TLS segment. Comment in the Linux source says wine might + * do that. + */ + + /* + * GLIBC reads current %gs and call set_thread_area() with it. + * We should let GUDATA_SEL and GUGS32_SEL proceed as well because + * we use these segments. + */ + switch (info.entry_number) { + case GUGS32_SEL: + case GUDATA_SEL: + case 6: + case -1: + info.entry_number = GUGS32_SEL; + break; + default: + return (EINVAL); + } + + /* + * We have to copy out the GDT entry we use. + * XXX: What if userspace program does not check return value and + * tries to use 6, 7 or 8? + */ + error = copyout(&info, args->desc, sizeof(struct l_user_desc)); + if (error) + return (error); + + if (LINUX_LDT_empty(&info)) { + a[0] = 0; + a[1] = 0; + } else { + a[0] = LINUX_LDT_entry_a(&info); + a[1] = LINUX_LDT_entry_b(&info); + } + + memcpy(&sd, &a, sizeof(a)); +#ifdef DEBUG + if (ldebug(set_thread_area)) + printf("Segment created in set_thread_area: " + "lobase: %x, hibase: %x, lolimit: %x, hilimit: %x, " + "type: %i, dpl: %i, p: %i, xx: %i, long: %i, " + "def32: %i, gran: %i\n", + sd.sd_lobase, + sd.sd_hibase, + sd.sd_lolimit, + sd.sd_hilimit, + sd.sd_type, + sd.sd_dpl, + sd.sd_p, + sd.sd_xx, + sd.sd_long, + sd.sd_def32, + sd.sd_gran); +#endif + + critical_enter(); + td->td_pcb->pcb_gsbase = (register_t)info.base_addr; + td->td_pcb->pcb_gs32sd = gdt[GUGS32_SEL] = sd; + td->td_pcb->pcb_gs32p = &gdt[GUGS32_SEL]; + td->td_pcb->pcb_flags |= PCB_32BIT; + wrmsr(MSR_KGSBASE, td->td_pcb->pcb_gsbase); + critical_exit(); - bsd_args.addr = uap->addr; - bsd_args.len = uap->len; - bsd_args.prot = uap->prot; - if (bsd_args.prot & (PROT_READ | PROT_WRITE | PROT_EXEC)) - bsd_args.prot |= PROT_READ | PROT_EXEC; - return (mprotect(td, &bsd_args)); + return (0); } ==== //depot/projects/uart/amd64/linux32/linux32_proto.h#13 (text+ko) ==== @@ -2,8 +2,8 @@ * System call prototypes. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/amd64/linux32/linux32_proto.h,v 1.29 2007/02/15 01:15:31 jkim Exp $ - * created from FreeBSD: src/sys/amd64/linux32/syscalls.master,v 1.26 2007/02/15 01:13:36 jkim Exp + * $FreeBSD: src/sys/amd64/linux32/linux32_proto.h,v 1.31 2007/03/30 00:08:21 jkim Exp $ + * created from FreeBSD: src/sys/amd64/linux32/syscalls.master,v 1.28 2007/03/30 00:06:21 jkim Exp */ #ifndef _LINUX_SYSPROTO_H_ @@ -734,6 +734,9 @@ char uaddr2_l_[PADL_(void *)]; void * uaddr2; char uaddr2_r_[PADR_(void *)]; char val3_l_[PADL_(int)]; int val3; char val3_r_[PADR_(int)]; }; +struct linux_set_thread_area_args { + char desc_l_[PADL_(struct l_user_desc *)]; struct l_user_desc * desc; char desc_r_[PADR_(struct l_user_desc *)]; +}; struct linux_fadvise64_args { register_t dummy; }; @@ -871,7 +874,10 @@ register_t dummy; }; struct linux_openat_args { - register_t dummy; + char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; + char filename_l_[PADL_(char *)]; char * filename; char filename_r_[PADR_(char *)]; + char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)]; + char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)]; }; struct linux_mkdirat_args { register_t dummy; @@ -1093,6 +1099,7 @@ int linux_fremovexattr(struct thread *, struct linux_fremovexattr_args *); int linux_tkill(struct thread *, struct linux_tkill_args *); int linux_sys_futex(struct thread *, struct linux_sys_futex_args *); +int linux_set_thread_area(struct thread *, struct linux_set_thread_area_args *); int linux_fadvise64(struct thread *, struct linux_fadvise64_args *); int linux_exit_group(struct thread *, struct linux_exit_group_args *); int linux_lookup_dcookie(struct thread *, struct linux_lookup_dcookie_args *); @@ -1339,6 +1346,7 @@ #define LINUX_SYS_AUE_linux_fremovexattr AUE_NULL #define LINUX_SYS_AUE_linux_tkill AUE_NULL #define LINUX_SYS_AUE_linux_sys_futex AUE_NULL +#define LINUX_SYS_AUE_linux_set_thread_area AUE_NULL #define LINUX_SYS_AUE_linux_fadvise64 AUE_NULL #define LINUX_SYS_AUE_linux_exit_group AUE_EXIT #define LINUX_SYS_AUE_linux_lookup_dcookie AUE_NULL @@ -1381,7 +1389,7 @@ #define LINUX_SYS_AUE_linux_inotify_add_watch AUE_NULL #define LINUX_SYS_AUE_linux_inotify_rm_watch AUE_NULL #define LINUX_SYS_AUE_linux_migrate_pages AUE_NULL -#define LINUX_SYS_AUE_linux_openat AUE_NULL +#define LINUX_SYS_AUE_linux_openat AUE_OPEN_RWTC #define LINUX_SYS_AUE_linux_mkdirat AUE_NULL #define LINUX_SYS_AUE_linux_mknodat AUE_NULL #define LINUX_SYS_AUE_linux_fchownat AUE_NULL ==== //depot/projects/uart/amd64/linux32/linux32_syscall.h#13 (text+ko) ==== @@ -2,8 +2,8 @@ * System call numbers. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/amd64/linux32/linux32_syscall.h,v 1.29 2007/02/15 01:15:31 jkim Exp $ - * created from FreeBSD: src/sys/amd64/linux32/syscalls.master,v 1.26 2007/02/15 01:13:36 jkim Exp + * $FreeBSD: src/sys/amd64/linux32/linux32_syscall.h,v 1.31 2007/03/30 00:08:21 jkim Exp $ + * created from FreeBSD: src/sys/amd64/linux32/syscalls.master,v 1.28 2007/03/30 00:06:21 jkim Exp */ #define LINUX_SYS_exit 1 @@ -222,6 +222,7 @@ #define LINUX_SYS_linux_fremovexattr 237 #define LINUX_SYS_linux_tkill 238 #define LINUX_SYS_linux_sys_futex 240 +#define LINUX_SYS_linux_set_thread_area 243 #define LINUX_SYS_linux_fadvise64 250 #define LINUX_SYS_linux_exit_group 252 #define LINUX_SYS_linux_lookup_dcookie 253 ==== //depot/projects/uart/amd64/linux32/linux32_sysent.c#13 (text+ko) ==== @@ -2,8 +2,8 @@ * System call switch table. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/amd64/linux32/linux32_sysent.c,v 1.29 2007/02/15 01:15:31 jkim Exp $ - * created from FreeBSD: src/sys/amd64/linux32/syscalls.master,v 1.26 2007/02/15 01:13:36 jkim Exp + * $FreeBSD: src/sys/amd64/linux32/linux32_sysent.c,v 1.31 2007/03/30 00:08:21 jkim Exp $ + * created from FreeBSD: src/sys/amd64/linux32/syscalls.master,v 1.28 2007/03/30 00:06:21 jkim Exp */ #include <bsm/audit_kevents.h> @@ -263,7 +263,7 @@ { AS(linux_sys_futex_args), (sy_call_t *)linux_sys_futex, AUE_NULL, NULL, 0, 0 }, /* 240 = linux_sys_futex */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 241 = linux_sched_setaffinity */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 242 = linux_sched_getaffinity */ - { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 243 = linux_set_thread_area */ + { AS(linux_set_thread_area_args), (sy_call_t *)linux_set_thread_area, AUE_NULL, NULL, 0, 0 }, /* 243 = linux_set_thread_area */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 244 = linux_get_thread_area */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 245 = linux_io_setup */ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 246 = linux_io_destroy */ @@ -315,7 +315,7 @@ { 0, (sy_call_t *)linux_inotify_add_watch, AUE_NULL, NULL, 0, 0 }, /* 292 = linux_inotify_add_watch */ { 0, (sy_call_t *)linux_inotify_rm_watch, AUE_NULL, NULL, 0, 0 }, /* 293 = linux_inotify_rm_watch */ { 0, (sy_call_t *)linux_migrate_pages, AUE_NULL, NULL, 0, 0 }, /* 294 = linux_migrate_pages */ - { 0, (sy_call_t *)linux_openat, AUE_NULL, NULL, 0, 0 }, /* 295 = linux_openat */ + { AS(linux_openat_args), (sy_call_t *)linux_openat, AUE_OPEN_RWTC, NULL, 0, 0 }, /* 295 = linux_openat */ { 0, (sy_call_t *)linux_mkdirat, AUE_NULL, NULL, 0, 0 }, /* 296 = linux_mkdirat */ { 0, (sy_call_t *)linux_mknodat, AUE_NULL, NULL, 0, 0 }, /* 297 = linux_mknodat */ { 0, (sy_call_t *)linux_fchownat, AUE_NULL, NULL, 0, 0 }, /* 298 = linux_fchownat */ ==== //depot/projects/uart/amd64/linux32/linux32_sysvec.c#14 (text+ko) ==== @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/amd64/linux32/linux32_sysvec.c,v 1.26 2006/12/03 21:06:07 netchild Exp $"); >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200703301825.l2UIPvIU063960>