From patchwork Tue Feb 16 10:31:19 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Casadevall X-Patchwork-Id: 45460 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id CF679B7C09 for ; Tue, 16 Feb 2010 21:40:54 +1100 (EST) Received: from localhost ([127.0.0.1]:46056 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NhKnL-0001AY-VS for incoming@patchwork.ozlabs.org; Tue, 16 Feb 2010 05:36:44 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NhKie-0000ZI-9Z for qemu-devel@nongnu.org; Tue, 16 Feb 2010 05:31:52 -0500 Received: from [199.232.76.173] (port=57854 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NhKid-0000Z6-KQ for qemu-devel@nongnu.org; Tue, 16 Feb 2010 05:31:51 -0500 Received: from Debian-exim by monty-python.gnu.org with spam-scanned (Exim 4.60) (envelope-from ) id 1NhKib-0004SF-4P for qemu-devel@nongnu.org; Tue, 16 Feb 2010 05:31:51 -0500 Received: from mail-vw0-f45.google.com ([209.85.212.45]:53792) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1NhKia-0004RZ-Qq for qemu-devel@nongnu.org; Tue, 16 Feb 2010 05:31:48 -0500 Received: by mail-vw0-f45.google.com with SMTP id 17so211519vws.4 for ; Tue, 16 Feb 2010 02:31:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:sender:received:from:to:cc :subject:date:message-id:x-mailer:in-reply-to:references; bh=5BsL5239f81ddYTK1wwB5zSM2kNXcn/q80m0tkurPfU=; b=VpejwO0WWnnWtuzxoKWRK9NnN5BjTpZLutOoxFKxak7EgWLIs4/THHjNynfzuVpi0o 0m+cM8LvvFiWZeY0vfqa0qbx2cP4/niifwKqttuXUlU3133f7gRlU6ywJ+SKJomhnqJx e3EMxD8FzvzayedNymWuoZuTwIWTDmeiz7eYE= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; b=tL+ofQ7CwHDBEX0JtvErPSuFLJKP1LE/zCkMbo95ANkC/vgE/1tgyu13v71GgzsHC7 g+Dom0a4LjFgSxsX63IDf2gsRG76apHieIFVDBC8jLSP9SowpLQ0lnwT4HeFB6FucTm+ pu8z40pKkttW6iFRuuHOBI8EL7grmdzghAnUE= Received: by 10.220.76.137 with SMTP id c9mr698366vck.205.1266316308395; Tue, 16 Feb 2010 02:31:48 -0800 (PST) Received: from daybreak.cofederation.dynalias.com (cpe-74-74-175-159.rochester.res.rr.com [74.74.175.159]) by mx.google.com with ESMTPS id 22sm6225515vws.14.2010.02.16.02.31.46 (version=TLSv1/SSLv3 cipher=RC4-MD5); Tue, 16 Feb 2010 02:31:47 -0800 (PST) Received: from mcasadevall by daybreak.cofederation.dynalias.com with local (Exim 4.71) (envelope-from ) id 1NhKiX-0007Nb-0R; Tue, 16 Feb 2010 05:31:45 -0500 From: Michael Casadevall To: qemu-devel@nongnu.org Date: Tue, 16 Feb 2010 05:31:19 -0500 Message-Id: <1266316280-28271-2-git-send-email-mcasadevall@ubuntu.com> X-Mailer: git-send-email 1.6.6.1 In-Reply-To: <1266316280-28271-1-git-send-email-mcasadevall@ubuntu.com> References: <1266316280-28271-1-git-send-email-mcasadevall@ubuntu.com> X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 2) Cc: Michael Casadevall Subject: [Qemu-devel] [PATCH 1/2] This patch adds support for the pselect syscall in linux-user emulation and also adds several support functions required to translate the timespec structs between the target and the host. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Signed-off-by: Michael Casadevall --- linux-user/syscall.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 119 insertions(+), 0 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 9fb493f..3663451 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -850,6 +850,38 @@ static inline abi_long copy_to_user_timeval(abi_ulong target_tv_addr, return 0; } +static inline abi_long copy_from_user_timespec(struct timespec *ts, + abi_ulong target_ts_addr) +{ + struct target_timespec *target_ts; + + if (!lock_user_struct(VERIFY_READ, target_ts, target_ts_addr, 1)) + return -TARGET_EFAULT; + + __get_user(ts->tv_sec, &target_ts->tv_sec); + __get_user(ts->tv_nsec, &target_ts->tv_nsec); + + unlock_user_struct(target_ts, target_ts_addr, 0); + + return 0; +} + + +static inline abi_long copy_to_user_timespec(abi_ulong target_ts_addr, + const struct timespec *ts) +{ + struct target_timespec *target_ts; + + if (!lock_user_struct(VERIFY_WRITE, target_ts, target_ts_addr, 0)) + return -TARGET_EFAULT; + + __put_user(ts->tv_sec, &target_ts->tv_sec); + __put_user(ts->tv_nsec, &target_ts->tv_nsec); + + unlock_user_struct(target_ts, target_ts_addr, 1); + + return 0; +} #if defined(TARGET_NR_mq_open) && defined(__NR_mq_open) #include @@ -949,6 +981,75 @@ static abi_long do_select(int n, return ret; } +#ifdef TARGET_NR_pselect6 +/* do_pselect() must return target values and target errnos. */ +static abi_long do_pselect(int n, + abi_ulong rfd_addr, abi_ulong wfd_addr, + abi_ulong efd_addr, abi_ulong target_tv_addr, + abi_ulong set_addr) +{ + fd_set rfds, wfds, efds; + fd_set *rfds_ptr, *wfds_ptr, *efds_ptr; + struct timespec tv, *tv_ptr; + sigset_t set, *set_ptr; + abi_long ret; + + if (rfd_addr) { + if (copy_from_user_fdset(&rfds, rfd_addr, n)) + return -TARGET_EFAULT; + rfds_ptr = &rfds; + } else { + rfds_ptr = NULL; + } + if (wfd_addr) { + if (copy_from_user_fdset(&wfds, wfd_addr, n)) + return -TARGET_EFAULT; + wfds_ptr = &wfds; + } else { + wfds_ptr = NULL; + } + if (efd_addr) { + if (copy_from_user_fdset(&efds, efd_addr, n)) + return -TARGET_EFAULT; + efds_ptr = &efds; + } else { + efds_ptr = NULL; + } + + if (target_tv_addr) { + if (copy_from_user_timespec(&tv, target_tv_addr)) + return -TARGET_EFAULT; + tv_ptr = &tv; + } else { + tv_ptr = NULL; + } + + /* We don't need to return sigmask to target */ + if (set_addr) { + target_to_host_old_sigset(&set, &set_addr); + set_ptr = &set; + } else { + set_ptr = NULL; + } + + ret = get_errno(pselect(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr, set_ptr)); + + if (!is_error(ret)) { + if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n)) + return -TARGET_EFAULT; + if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n)) + return -TARGET_EFAULT; + if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n)) + return -TARGET_EFAULT; + + if (target_tv_addr && copy_to_user_timespec(target_tv_addr, &tv)) + return -TARGET_EFAULT; + } + + return ret; +} +#endif + static abi_long do_pipe2(int host_pipe[], int flags) { #ifdef CONFIG_PIPE2 @@ -5136,6 +5237,24 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, } break; #endif + +#ifdef TARGET_NR_pselect6 + case TARGET_NR_pselect6: + { + abi_ulong inp, outp, exp, tvp, set; + long nsel; + + nsel = tswapl(arg1); + inp = tswapl(arg2); + outp = tswapl(arg3); + exp = tswapl(arg4); + tvp = tswapl(arg5); + set = tswapl(arg6); + + ret = do_pselect(nsel, inp, outp, exp, tvp, set); + } + break; +#endif case TARGET_NR_symlink: { void *p2;