From owner-freebsd-bugs Tue Nov 26 21:30: 9 2002 Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 87B9137B401 for ; Tue, 26 Nov 2002 21:30:02 -0800 (PST) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9122143EC2 for ; Tue, 26 Nov 2002 21:30:01 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.6/8.12.6) with ESMTP id gAR5U1x3042387 for ; Tue, 26 Nov 2002 21:30:01 -0800 (PST) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.6/8.12.6/Submit) id gAR5U1nk042386; Tue, 26 Nov 2002 21:30:01 -0800 (PST) Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id AACE637B401 for ; Tue, 26 Nov 2002 21:21:06 -0800 (PST) Received: from alpha.yumyumyum.org (dsl092-171-091.wdc1.dsl.speakeasy.net [66.92.171.91]) by mx1.FreeBSD.org (Postfix) with ESMTP id 0DF4243EB2 for ; Tue, 26 Nov 2002 21:21:00 -0800 (PST) (envelope-from culverk@alpha.yumyumyum.org) Received: from alpha.yumyumyum.org (localhost [127.0.0.1]) by alpha.yumyumyum.org (8.12.6/8.12.6) with ESMTP id gAR5ILrv035641 for ; Wed, 27 Nov 2002 00:18:21 -0500 (EST) (envelope-from culverk@alpha.yumyumyum.org) Received: (from culverk@localhost) by alpha.yumyumyum.org (8.12.6/8.12.6/Submit) id gAR5ILlX035640; Wed, 27 Nov 2002 00:18:21 -0500 (EST) (envelope-from culverk) Message-Id: <200211270518.gAR5ILlX035640@alpha.yumyumyum.org> Date: Wed, 27 Nov 2002 00:18:21 -0500 (EST) From: Kenneth Culver Reply-To: Kenneth Culver To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Subject: kern/45785: Linux WineX seems to require a few new linux syscalls Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org >Number: 45785 >Category: kern >Synopsis: Linux WineX seems to require a few new linux syscalls >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Nov 26 21:30:01 PST 2002 >Closed-Date: >Last-Modified: >Originator: Kenneth Culver >Release: FreeBSD 4.7-STABLE i386 >Organization: none >Environment: System: FreeBSD kenshin.yumyumyum.org 4.7-STABLE FreeBSD 4.7-STABLE #0: Tue Nov 26 21:21:26 EST 2002 culverk@kenshin.yumyumyum.org:/usr/src/sys/compile/MYKERNEL i386 >Description: The problem is very simple: WineX, as far as I can tell, won't work properly without mmap2 and ftruncate64 linux syscalls. To fix The problem I implemented those syscalls, and since I was there I did truncate64 as well. >How-To-Repeat: Just run WineX without my linux patches... and watch the console log for a message about mmap2 not being implemented. >Fix: Here is the fix... I guess cut 'n paste them to a file, then patch from /usr/src/sys Index: compat/linux/linux_file.c =================================================================== RCS file: /usr/home/ncvs/src/sys/compat/linux/linux_file.c,v retrieving revision 1.41.2.5 diff -u -r1.41.2.5 linux_file.c --- compat/linux/linux_file.c 5 Nov 2001 19:08:22 -0000 1.41.2.5 +++ compat/linux/linux_file.c 27 Nov 2002 02:11:57 -0000 @@ -654,6 +654,37 @@ } int +linux_truncate64(struct proc *p, struct linux_truncate64_args *args) +{ + struct truncate_args bsd; + caddr_t sg; + + sg = stackgap_init(); + CHECKALTEXIST(p, &sg, args->path); + +#ifdef DEBUG + if (ldebug(truncate)) + printf(ARGS(truncate, "%s, %ld"), args->path, + (long)args->length); +#endif + bsd.path = args->path; + bsd.length = args->length; + + return truncate(p, &bsd); +} + +int +linux_ftruncate64(struct proc *p, struct linux_ftruncate64_args *args) +{ + struct ftruncate_args bsd; + + bsd.fd = args->fd; + bsd.length = args->length; + + return ftruncate(p, &bsd); +} + +int linux_link(struct proc *p, struct linux_link_args *args) { struct link_args bsd; Index: i386/linux/linux_dummy.c =================================================================== RCS file: /usr/home/ncvs/src/sys/i386/linux/linux_dummy.c,v retrieving revision 1.21.2.6 diff -u -r1.21.2.6 linux_dummy.c --- i386/linux/linux_dummy.c 5 Nov 2001 19:08:23 -0000 1.21.2.6 +++ i386/linux/linux_dummy.c 27 Nov 2002 02:02:57 -0000 @@ -65,9 +65,6 @@ DUMMY(capget); DUMMY(capset); DUMMY(sendfile); -DUMMY(mmap2); -DUMMY(truncate64); -DUMMY(ftruncate64); DUMMY(setfsuid); DUMMY(setfsgid); DUMMY(pivot_root); Index: i386/linux/linux_machdep.c =================================================================== RCS file: /usr/home/ncvs/src/sys/i386/linux/linux_machdep.c,v retrieving revision 1.6.2.4 diff -u -r1.6.2.4 linux_machdep.c --- i386/linux/linux_machdep.c 5 Nov 2001 19:08:23 -0000 1.6.2.4 +++ i386/linux/linux_machdep.c 27 Nov 2002 02:07:55 -0000 @@ -381,6 +381,120 @@ #define GUARD_SIZE (4 * PAGE_SIZE) int +linux_mmap2(struct proc *p, struct linux_mmap2_args *linux_args) +{ + struct mmap_args /* { + caddr_t addr; + size_t len; + int prot; + int flags; + int fd; + long pad; + off_t pos; + } */ bsd_args; + +#ifdef DEBUG + if (ldebug(mmap2)) + printf(ARGS(mmap2, "%p, %d, %d, 0x%08x, %d, %d"), + (void *)linux_args->addr, linux_args->len, linux_args->prot, + linux_args->flags, linux_args->fd, linux_args->pos); +#endif + + bsd_args.flags = 0; + if (linux_args->flags & LINUX_MAP_SHARED) + bsd_args.flags |= MAP_SHARED; + if (linux_args->flags & LINUX_MAP_PRIVATE) + bsd_args.flags |= MAP_PRIVATE; + if (linux_args->flags & LINUX_MAP_FIXED) + bsd_args.flags |= MAP_FIXED; + if (linux_args->flags & LINUX_MAP_ANON) + bsd_args.flags |= MAP_ANON; + else + bsd_args.flags |= MAP_NOSYNC; + if (linux_args->flags & LINUX_MAP_GROWSDOWN) { + bsd_args.flags |= MAP_STACK; + + /* 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 to stack size of STACK_SIZE. Its just not + * 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. + * + * Our mmap with MAP_STACK takes addr as the maximum + * downsize limit on BOS, and as len the max size of + * the region. It them maps the top SGROWSIZ bytes, + * and autgrows the region down, up to the limit + * in addr. + * + * If we don't use the MAP_STACK option, the effect + * of this code is to allocate a stack region of a + * fixed size of (STACK_SIZE - GUARD_SIZE). + */ + + /* This gives us TOS */ + bsd_args.addr = (caddr_t)(linux_args->addr + linux_args->len); + + if (bsd_args.addr > p->p_vmspace->vm_maxsaddr) { + /* 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() + * will confuse the thread stack with the + * process stack and deliver a SEGV if they + * attempt to grow the thread stack past their + * current stacksize rlimit. To avoid this, + * adjust vm_maxsaddr upwards to reflect + * the current stacksize rlimit rather + * than the maximum possible stacksize. + * It would be better to adjust the + * mmap'ed region, but some apps do not check + * mmap's return value. + */ + p->p_vmspace->vm_maxsaddr = (char *)USRSTACK - + p->p_rlimit[RLIMIT_STACK].rlim_cur; + } + + /* This gives us our maximum stack size */ + if (linux_args->len > STACK_SIZE - GUARD_SIZE) + bsd_args.len = linux_args->len; + 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 + * not using VM_STACK we map the full stack, since we + * don't have a way to autogrow it. + */ + bsd_args.addr -= bsd_args.len; + } else { + bsd_args.addr = (caddr_t)linux_args->addr; + bsd_args.len = linux_args->len; + } + + bsd_args.prot = linux_args->prot | PROT_READ; /* always required */ + if (linux_args->flags & LINUX_MAP_ANON) + bsd_args.fd = -1; + else + bsd_args.fd = linux_args->fd; + bsd_args.pos = ctob(linux_args->pgoff); + bsd_args.pad = 0; + +#ifdef DEBUG + if (ldebug(mmap2)) + printf("-> (%p, %d, %d, 0x%08x, %d, %d)\n", + (void *)bsd_args.addr, bsd_args.len, bsd_args.prot, + bsd_args.flags, bsd_args.fd, (int)bsd_args.pos); +#endif + + return (mmap(p, &bsd_args)); +} + +int linux_mmap(struct proc *p, struct linux_mmap_args *args) { struct mmap_args /* { Index: i386/linux/linux_sysvec.c =================================================================== RCS file: /usr/home/ncvs/src/sys/i386/linux/linux_sysvec.c,v retrieving revision 1.55.2.9 diff -u -r1.55.2.9 linux_sysvec.c --- i386/linux/linux_sysvec.c 12 Jan 2002 11:03:30 -0000 1.55.2.9 +++ i386/linux/linux_sysvec.c 27 Nov 2002 02:02:57 -0000 @@ -722,6 +722,7 @@ args[2] = tf->tf_edx; args[3] = tf->tf_esi; args[4] = tf->tf_edi; + args[5] = tf->tf_ebp; /* tf_ebp taken from linux glibc sources */ *params = NULL; /* no copyin */ } >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message