From culverk@alpha.yumyumyum.org  Tue Nov 26 21:21:06 2002
Return-Path: <culverk@alpha.yumyumyum.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id AACE637B401
	for <FreeBSD-gnats-submit@freebsd.org>; 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 <FreeBSD-gnats-submit@freebsd.org>; 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 <FreeBSD-gnats-submit@freebsd.org>; 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 <culverk@yumyumyum.org>
Reply-To: Kenneth Culver <culverk@yumyumyum.org>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: Linux WineX seems to require a few new linux syscalls	
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         45785
>Category:       kern
>Synopsis:       Linux WineX seems to require a few new linux syscalls
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    emulation
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Nov 26 21:30:01 PST 2002
>Closed-Date:    Mon Nov 08 08:08:58 GMT 2004
>Last-Modified:  Wed Nov 17 00:50:32 GMT 2004
>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:
Responsible-Changed-From-To: freebsd-bugs->freebsd-emulation 
Responsible-Changed-By: gerald 
Responsible-Changed-When: Sun Apr 27 04:55:12 PDT 2003 
Responsible-Changed-Why:  
Over to freebsd-emulation.  This contains a patch! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=45785 
Responsible-Changed-From-To: freebsd-emulation->emulation 
Responsible-Changed-By: gerald 
Responsible-Changed-When: Mon Jul 28 14:12:05 PDT 2003 
Responsible-Changed-Why:  
Reassign to emulation@ to avoid getting two "Current problem reports assigned 
to you". 

http://www.freebsd.org/cgi/query-pr.cgi?pr=45785 

From: No Name <arundel@h3c.de>
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 ---
 
State-Changed-From-To: open->feedback 
State-Changed-By: bms 
State-Changed-When: Mon Nov 8 08:03:54 GMT 2004 
State-Changed-Why:  
5.3 is the new -STABLE. 
Most of the functionality of this patch seems to be in -STABLE, with 
the exception of linux_truncate64(). Is this call absolutely necessary? 

http://www.freebsd.org/cgi/query-pr.cgi?pr=45785 
State-Changed-From-To: feedback->closed 
State-Changed-By: bms 
State-Changed-When: Mon Nov 8 08:08:37 GMT 2004 
State-Changed-Why:  
Most of this is in 5.3, and submitter's email bounces 

http://www.freebsd.org/cgi/query-pr.cgi?pr=45785 

From: No Name <arundel@h3c.de>
To: FreeBSD-gnats-submit@freebsd.org
Cc:  
Subject: Re: kern/45785: Linux WineX seems to require a few new linux syscalls
Date: Wed, 17 Nov 2004 01:46:49 +0100 (CET)

 >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:         change-request
 >Release:       FreeBSD 5.3-RELEASE i386
 >Environment:
 System: FreeBSD skatecity 5.3-RELEASE FreeBSD 5.3-RELEASE #3: Mon Nov 8 01:54:22 CET 2004 arundel@skatecity:/usr/obj/usr/src/sys/ARUNDEL i386
 
 >Description:
 	The only app that I came across that uses ftruncate64 is the linux-edonkey-core
 	version 1.0.2 (PR: ports/71706). This is the warning that was issued:
 
 	linux: pid 13165 (donkey): syscall truncate64 not implemented
 
 	Since the code for the syscall already exists I don't see why it shouldn't be
 	embedded into the -STABLE linux compat src.
 
 >How-To-Repeat:
 	
 >Fix:
 
 	
 
 
>Unformatted:
