PERFORCE change 116949 for review
Marcel Moolenaar
marcel at FreeBSD.org
Fri Mar 30 18:26:00 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=116949
Change 116949 by marcel at 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) <<<
More information about the p4-projects
mailing list