From owner-freebsd-emulation@FreeBSD.ORG Mon Aug 23 20:40:31 2004 Return-Path: Delivered-To: freebsd-emulation@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 976E416A4D4 for ; Mon, 23 Aug 2004 20:40:31 +0000 (GMT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 78BAF43D78 for ; Mon, 23 Aug 2004 20:40:31 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.11/8.12.11) with ESMTP id i7NKeV4k041261 for ; Mon, 23 Aug 2004 20:40:31 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.11/8.12.11/Submit) id i7NKeVWM041260; Mon, 23 Aug 2004 20:40:31 GMT (envelope-from gnats) Date: Mon, 23 Aug 2004 20:40:31 GMT Message-Id: <200408232040.i7NKeVWM041260@freefall.freebsd.org> To: emulation@FreeBSD.org From: No Name Subject: Re: kern/45785: Linux WineX seems to require a few new linux syscalls X-BeenThere: freebsd-emulation@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: No Name List-Id: Development of Emulators of other operating systems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 23 Aug 2004 20:40:31 -0000 The following reply was made to PR kern/45785; it has been noted by GNATS. From: No Name To: FreeBSD-gnats-submit@freebsd.org Cc: Subject: Re: kern/45785: Linux WineX seems to require a few new linux syscalls Date: Mon, 23 Aug 2004 22:41:53 +0200 (CEST) >Submitter-Id: current-users >Originator: No Name >Organization: >Confidential: no >Synopsis: Re: kern/45785: Linux WineX seems to require a few new linux syscalls >Severity: non-critical >Priority: medium >Category: kern >Class: sw-bug >Release: FreeBSD 4.10-STABLE i386 >Environment: System: FreeBSD skatecity 4.10-STABLE FreeBSD 4.10-STABLE #0: Mon Aug 23 20:56:48 CEST 2004 arundel@skatecity:/usr/obj/usr/src/sys/ARUNDEL i386 >Description: I don't know abou the current state of mmap2 in -STABLE, but I got really pissed with the constant error output to tty. Since the original patch by Kenneth does not apply 100% clean to RELENG_4 I made a few dirty changes to it. Surprisingly I got an increas of roughly 70 frames running this patch and quake3-linux (timedemo 1 - four.dm_68). >How-To-Repeat: >Fix: --- mmap2-patch.diff begins here --- --- compat/linux/linux_file.c.orig Mon Aug 23 21:19:35 2004 +++ compat/linux/linux_file.c Mon Aug 23 21:39:21 2004 @@ -685,6 +685,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; --- i386/linux/linux_dummy.c.orig Mon Aug 23 21:19:35 2004 +++ i386/linux/linux_dummy.c Mon Aug 23 21:37:54 2004 @@ -64,8 +64,6 @@ DUMMY(capget); DUMMY(capset); DUMMY(sendfile); -DUMMY(mmap2); -DUMMY(truncate64); DUMMY(setfsuid); DUMMY(setfsgid); DUMMY(pivot_root); --- i386/linux/linux_machdep.c.orig Mon Aug 23 21:19:35 2004 +++ i386/linux/linux_machdep.c Mon Aug 23 21:41:57 2004 @@ -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 /* { @@ -790,7 +904,7 @@ return (error); } -int +/* int linux_ftruncate64(struct proc *p, struct linux_ftruncate64_args *args) { struct ftruncate_args sa; @@ -804,4 +918,4 @@ sa.pad = 0; sa.length = args->length; return ftruncate(p, &sa); -} +} */ --- i386/linux/linux_sysvec.c.orig Mon Aug 23 21:19:35 2004 +++ i386/linux/linux_sysvec.c Mon Aug 23 21:33:06 2004 @@ -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 */ } --- mmap2-patch.diff ends here ---