From owner-freebsd-emulation@FreeBSD.ORG Tue Sep 19 00:37:10 2006 Return-Path: X-Original-To: emulation@freebsd.org 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 7B04C16A40F for ; Tue, 19 Sep 2006 00:37:10 +0000 (UTC) (envelope-from saper@SYSTEM.PL) Received: from mail01.ish.de (pip249.ish.de [80.69.98.249]) by mx1.FreeBSD.org (Postfix) with ESMTP id 6445043D49 for ; Tue, 19 Sep 2006 00:37:09 +0000 (GMT) (envelope-from saper@SYSTEM.PL) Received: from [81.210.201.87] (account saper@iesy.net HELO saperski.saper.info) by mail-fe-02.mail01.ish.de (CommuniGate Pro SMTP 5.0.6) with ESMTPSA id 67267536 for emulation@freebsd.org; Tue, 19 Sep 2006 02:37:05 +0200 Received: from [127.0.0.1] (saperski.saper.info [127.0.0.1]) by saperski.saper.info (8.13.8/8.13.8) with ESMTP id k8J0apgb006264 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL) for ; Tue, 19 Sep 2006 02:36:58 +0200 (CEST) (envelope-from saper@SYSTEM.PL) Message-ID: <450F3BA3.40304@SYSTEM.PL> Date: Tue, 19 Sep 2006 02:36:51 +0200 From: Marcin Cieslak User-Agent: Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.8.0.6) Gecko/20060912 SeaMonkey/1.0.4 MIME-Version: 1.0 To: emulation@freebsd.org Content-Type: text/plain; charset=ISO-8859-2; format=flowed Content-Transfer-Encoding: 7bit Cc: Subject: i386 mmap(2) fixed for LTP X-BeenThere: freebsd-emulation@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Development of Emulators of other operating systems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 19 Sep 2006 00:37:10 -0000 Hallo, Using my mmap fingerprinter (see amd64 post above) I have managed to compare basic mmap(2) behaviour between real Linux and FreeBSD machine. Our mmap(2) allows you map write-only file for writing, Linux is giving up immediately on that. (Probably because they always need the file to be open for reading as well and then they add PROT_READ internally). Using this patch I guess we have all mmap()-related LTP issues solved. This fixes outstanding map07 test. I guess that writev03 and writev04 - that started to fail after my initial quick fix for mmap() - were just false positives initially. Since linuxolator mmap() added PROT_READ that gave access to whole iovec address space, writev() calls suceeded although not in a way meant by author tests: http://sf.net/tracker/index.php?func=detail&aid=1561083&group_id=3382&atid=103382 The only thing left is the amd64 part of the fix for mmap(2). Please feel free to review. -- << Marcin Cieslak // saper@system.pl >> Index: /usr/src/sys/i386/linux/linux_machdep.c =================================================================== RCS file: /usr/home/ncvs/src/sys/i386/linux/linux_machdep.c,v retrieving revision 1.48.2.1 diff -u -u -r1.48.2.1 linux_machdep.c --- /usr/src/sys/i386/linux/linux_machdep.c 4 Aug 2005 23:25:32 -0000 1.48.2.1 +++ /usr/src/sys/i386/linux/linux_machdep.c 19 Sep 2006 00:34:53 -0000 @@ -31,6 +31,8 @@ #include #include +#include +#include #include #include #include @@ -469,9 +471,19 @@ off_t pos; } */ bsd_args; int error; + struct file *fp; error = 0; bsd_args.flags = 0; + fp = NULL; + + /* Linux mmap(2): + * You must specify exactly one of MAP_SHARED and MAP_PRIVATE. + */ + if (! ((linux_args->flags & LINUX_MAP_SHARED) ^ + (linux_args->flags & LINUX_MAP_PRIVATE))) + return EINVAL; + if (linux_args->flags & LINUX_MAP_SHARED) bsd_args.flags |= MAP_SHARED; if (linux_args->flags & LINUX_MAP_PRIVATE) @@ -549,11 +561,34 @@ 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.prot = linux_args->prot; + if (linux_args->flags & LINUX_MAP_ANON) { bsd_args.fd = -1; - else + } else { + /* + * Linux follows Solaris mmap(2) description: + * The file descriptor fildes is opened with + * read permission, regardless of the + * protection options specified. + * If PROT_WRITE is specified, the application + * must have opened the file descriptor + * fildes with write permission unless + * MAP_PRIVATE is specified in the flags + * argument as described below. + */ + + if ((error = fget(td, linux_args->fd, &fp)) != 0) + return error; + if (fp->f_type != DTYPE_VNODE) + return EINVAL; + + /* Linux mmap() just fails for O_WRONLY files */ + if (! (fp->f_flag & FREAD)) + return EACCES; + bsd_args.fd = linux_args->fd; + fdrop(fp, td); + } bsd_args.pos = linux_args->pos; bsd_args.pad = 0;