Skip site navigation (1)Skip section navigation (2)
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>