From patchwork Thu Sep 13 15:50:12 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Catalin Marinas X-Patchwork-Id: 1453501 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from merlin.infradead.org (unknown [205.233.59.134]) by patchwork2.kernel.org (Postfix) with ESMTP id 45071DF24C for ; Thu, 13 Sep 2012 16:09:02 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TCBhU-0004qV-JU; Thu, 13 Sep 2012 15:51:32 +0000 Received: from cam-admin0.cambridge.arm.com ([217.140.96.50]) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TCBhO-0004aa-53 for linux-arm-kernel@lists.infradead.org; Thu, 13 Sep 2012 15:51:28 +0000 Received: from arm.com (e102109-lin.cambridge.arm.com [10.1.69.68]) by cam-admin0.cambridge.arm.com (8.12.6/8.12.6) with ESMTP id q8DFolE7021050; Thu, 13 Sep 2012 16:50:47 +0100 (BST) Date: Thu, 13 Sep 2012 16:50:12 +0100 From: Catalin Marinas To: Arnd Bergmann Subject: Re: [PATCH v3 21/31] arm64: 32-bit (compat) applications support Message-ID: <20120913155012.GC25131@arm.com> References: <1347035226-18649-1-git-send-email-catalin.marinas@arm.com> <201209071947.45313.arnd@arndb.de> <20120913090732.GA25131@arm.com> <201209131103.27387.arnd@arndb.de> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <201209131103.27387.arnd@arndb.de> User-Agent: Mutt/1.5.20 (2009-06-14) X-Spam-Note: CRM114 invocation failed X-Spam-Score: -7.4 (-------) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-7.4 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at http://www.dnswl.org/, high trust [217.140.96.50 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.5 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: "linux-arch@vger.kernel.org" , "linux-kernel@vger.kernel.org" , "linux-arm-kernel@lists.infradead.org" X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org On Thu, Sep 13, 2012 at 12:03:27PM +0100, Arnd Bergmann wrote: > On Thursday 13 September 2012, Catalin Marinas wrote: > > +#ifdef __ARCH_WANT_COMPAT_SYS_SENDFILE > > +asmlinkage int compat_sys_sendfile(int out_fd, int in_fd, > > + compat_off_t __user *offset, s32 count) > > +{ > > + mm_segment_t old_fs = get_fs(); > > + int ret; > > + off_t of; > > + > > + if (offset && get_user(of, offset)) > > + return -EFAULT; > > + > > + set_fs(KERNEL_DS); > > + ret = sys_sendfile(out_fd, in_fd, > > + offset ? (off_t __user *)&of : NULL, count); > > + set_fs(old_fs); > > + > > + if (offset && put_user(of, offset)) > > + return -EFAULT; > > + return ret; > > +} > > +#endif /* __ARCH_WANT_COMPAT_SYS_SENDFILE */ > > Looking at this code in detail now, I think it's better to move the functions to > fs/read_write.c and get rid of the get_fs/set_fs hack, like > > asmlinkage int compat_sys_sendfile(int out_fd, int in_fd, > compat_off_t __user *offset, s32 count) ... It makes sense (copied below, just for compat_sys_sendfile until my comments below are clarified). One minor improvement, I think we should use compat_size_t for the count, it is a u32 in all cases. > This implementation is smaller and more efficient than the common one. > > Same for compat_sys_sendfile64, although I don't think there is ever > a case where loff_t is defined differently from compat_loff_t, so > you can probably just use the native sys_sendfile64 for the compat > case. That's what we do on AArch64, though powerpc and sparc define their own. The "count" argument would be different between compat and non-compat versions and I'm not sure what assumptions are made on the syscall entry path on these architectures (on AArch64 we ensure that the top 32-bit part of an X register is always 0 for 32-bit syscalls). Another difference is that the "count" argument for compat_sys_sendfile64 is s32 on powerpc and u32 on sparc. I can't tell whether it would make a difference in practice but if we use compat_size_t for the generic version the powerpc wouldn't get the sign extension. Powerpc has some comment about a need to treat in_fd/out_fd arguments as signed ints but I don't fully understand it (well, maybe powerpc needs the sign to be fully extended to 64-bit even for int). ----------8<----------------------- From 7c6747fc9f69d20f445e4af69c644acb04a74f45 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Thu, 13 Sep 2012 09:51:10 +0100 Subject: [PATCH 1/3] Add generic compat_sys_sendfile implementation This function is used by other architectures requiring compat support, so just make it generic. Signed-off-by: Catalin Marinas Cc: Arnd Bergmann --- fs/read_write.c | 22 ++++++++++++++++++++++ include/linux/compat.h | 3 +++ 2 files changed, 25 insertions(+), 0 deletions(-) diff --git a/fs/read_write.c b/fs/read_write.c index 1adfb69..91b91c4 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -1007,3 +1007,25 @@ SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd, loff_t __user *, offset, si return do_sendfile(out_fd, in_fd, NULL, count, 0); } + +#ifdef __ARCH_WANT_COMPAT_SYS_SENDFILE +asmlinkage int compat_sys_sendfile(int out_fd, int in_fd, + compat_off_t __user *offset, compat_size_t count) +{ + loff_t pos; + off_t off; + ssize_t ret; + + if (offset) { + if (unlikely(get_user(off, offset))) + return -EFAULT; + pos = off; + ret = do_sendfile(out_fd, in_fd, &pos, count, MAX_NON_LFS); + if (unlikely(put_user(pos, offset))) + return -EFAULT; + return ret; + } + + return do_sendfile(out_fd, in_fd, NULL, count, 0); +} +#endif /* __ARCH_WANT_COMPAT_SYS_SENDFILE */ diff --git a/include/linux/compat.h b/include/linux/compat.h index c4be3f5..f386e82 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -594,6 +594,9 @@ asmlinkage ssize_t compat_sys_process_vm_writev(compat_pid_t pid, unsigned long liovcnt, const struct compat_iovec __user *rvec, unsigned long riovcnt, unsigned long flags); +asmlinkage int compat_sys_sendfile(int out_fd, int in_fd, + compat_off_t __user *offset, s32 count); + #else #define is_compat_task() (0)