From patchwork Sun Jun 10 03:01:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 927280 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="ZIxyNgpF"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 413Mlp6s3Sz9s1B for ; Sun, 10 Jun 2018 13:56:54 +1000 (AEST) Received: from localhost ([::1]:42471 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fRrTI-0001H3-Hy for incoming@patchwork.ozlabs.org; Sat, 09 Jun 2018 23:56:52 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40962) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fRqen-0003Rc-0D for qemu-devel@nongnu.org; Sat, 09 Jun 2018 23:04:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fRqel-0003sw-Os for qemu-devel@nongnu.org; Sat, 09 Jun 2018 23:04:41 -0400 Received: from mail-pf0-x242.google.com ([2607:f8b0:400e:c00::242]:34415) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fRqel-0003sS-Gw for qemu-devel@nongnu.org; Sat, 09 Jun 2018 23:04:39 -0400 Received: by mail-pf0-x242.google.com with SMTP id a63-v6so8499503pfl.1 for ; Sat, 09 Jun 2018 20:04:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=BEsMWgTH49iFDdmp2MfOksyWfRzKkXoFJXJNoz/B4uE=; b=ZIxyNgpFuvAyr5E57ap3hX87JqeMfymIqtoAiaeiIbTV1g0KzqEEmwPMvVeudlBePS TpPSVZI7V1VADyV4KEqaNjIcErju+cBRixSDUvA067VHopwinPMrTY8ghL+grEDs/i2O Ly1ROIc6aF/U6etclOG+sAvHWIejP+dgskS+U= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=BEsMWgTH49iFDdmp2MfOksyWfRzKkXoFJXJNoz/B4uE=; b=P7INpGEa27k2YHqBN/ufvNOdNws7P7hjdG3kVbdX4JW46rghJxSg9eLfgXuimxWM8t 0LbPfqnOAARUpNVBZFn6UAtwEu5ahwjUd3fnIcJMF/XYZ20nVmEENpheQmrLYInP3N7P QtETkffhH7FsPlLdGPW1EiEqTPVnrjeDZOkKXenXiphHxOh6OoNlalYUDEX+aTYU+rol QpGWdIWUqbnQiPp51AcPjrMNunJHEiMOYRb9puD57iI+ac6p/rFOQiIIR3rfSMYAIhvc qGXEp7NuuJnGx899jqoQstB4j6Fu0Ll7ktw7JCGCaBLnztJGq8dC01dRDXZhJBDgRMeB WWNQ== X-Gm-Message-State: APt69E37qvF/f29gVjR/DYwlLveVE+v69LWqCCEDA8DtwUZsI8oYJS85 R/DrEPlI0uXy8GKOpqP6+4Jcl3L4pAE= X-Google-Smtp-Source: ADUXVKJc92GFWVw3tZNQ1fIYWXE4zsFZd58i5geizzzdXvew+KrPObBSdQC7gtPQ2pugn1ecWGHF6w== X-Received: by 2002:a63:6742:: with SMTP id b63-v6mr10424258pgc.54.1528599878330; Sat, 09 Jun 2018 20:04:38 -0700 (PDT) Received: from cloudburst.twiddle.net (rrcs-173-198-77-219.west.biz.rr.com. [173.198.77.219]) by smtp.gmail.com with ESMTPSA id y17-v6sm31712718pfe.33.2018.06.09.20.04.36 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 09 Jun 2018 20:04:37 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 9 Jun 2018 17:01:33 -1000 Message-Id: <20180610030220.3777-62-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180610030220.3777-1-richard.henderson@linaro.org> References: <20180610030220.3777-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c00::242 Subject: [Qemu-devel] [PATCH v2 061/108] linux-user: Split out poll, ppoll X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" All targets define ppoll; remove the ifdef. Signed-off-by: Richard Henderson --- linux-user/syscall.c | 232 +++++++++++++++++++++++-------------------- 1 file changed, 124 insertions(+), 108 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 600702ea3e..362d315ce8 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -9101,6 +9101,126 @@ IMPL(pipe2) target_to_host_bitmask(arg2, fcntl_flags_tbl), 1); } +static struct pollfd *get_pollfd(abi_ulong nfds, abi_ulong target_addr, + struct target_pollfd **ptfd, abi_long *err) +{ + struct target_pollfd *target_pfd; + struct pollfd *pfd; + abi_ulong i; + + if (nfds > (INT_MAX / sizeof(struct target_pollfd))) { + *err = -TARGET_EINVAL; + return NULL; + } + pfd = g_try_new(struct pollfd, nfds); + if (pfd == NULL) { + *err = -TARGET_ENOMEM; + return NULL; + } + + *ptfd = target_pfd = lock_user(VERIFY_WRITE, target_addr, + sizeof(struct target_pollfd) * nfds, 1); + if (!target_pfd) { + *err = -TARGET_EFAULT; + g_free(pfd); + return NULL; + } + + for (i = 0; i < nfds; i++) { + pfd[i].fd = tswap32(target_pfd[i].fd); + pfd[i].events = tswap16(target_pfd[i].events); + } + + *err = 0; + return pfd; +} + +static abi_long put_pollfd(abi_ulong nfds, abi_ulong target_addr, + struct pollfd *pfd, + struct target_pollfd *target_pfd, abi_long ret) +{ + if (!is_error(ret)) { + abi_ulong i; + for (i = 0; i < nfds; i++) { + target_pfd[i].revents = tswap16(pfd[i].revents); + } + } + unlock_user(target_pfd, target_addr, sizeof(struct target_pollfd) * nfds); + g_free(pfd); + return ret; +} + +#ifdef TARGET_NR_poll +IMPL(poll) +{ + struct timespec ts, *pts; + struct target_pollfd *target_pfd; + struct pollfd *pfd; + abi_long ret; + + if (arg3 >= 0) { + /* Convert ms to secs, ns */ + ts.tv_sec = arg3 / 1000; + ts.tv_nsec = (arg3 % 1000) * 1000000LL; + pts = &ts; + } else { + /* -ve poll() timeout means "infinite" */ + pts = NULL; + } + + pfd = get_pollfd(arg2, arg1, &target_pfd, &ret); + if (pfd == NULL) { + return ret; + } + ret = safe_ppoll(pfd, arg2, pts, NULL, 0); + return put_pollfd(arg2, arg1, pfd, target_pfd, get_errno(ret)); +} +#endif + +IMPL(ppoll) +{ + struct timespec ts; + sigset_t set; + struct target_pollfd *target_pfd; + struct pollfd *pfd; + abi_long ret; + + if (arg3) { + if (target_to_host_timespec(&ts, arg3)) { + return -TARGET_EFAULT; + } + } + + if (arg4) { + target_sigset_t *target_set; + if (arg5 != sizeof(target_sigset_t)) { + return -TARGET_EINVAL; + } + target_set = lock_user(VERIFY_READ, arg4, sizeof(target_sigset_t), 1); + if (!target_set) { + return -TARGET_EFAULT; + } + target_to_host_sigset(&set, target_set); + unlock_user(target_set, arg4, 0); + } + + pfd = get_pollfd(arg2, arg1, &target_pfd, &ret); + if (pfd == NULL) { + return ret; + } + ret = safe_ppoll(pfd, arg2, arg3 ? &ts : NULL, + arg4 ? &set : NULL, SIGSET_T_SIZE); + ret = put_pollfd(arg2, arg1, pfd, target_pfd, get_errno(ret)); + + if (!is_error(ret) && arg3) { + abi_long err = host_to_target_timespec(arg3, &ts); + if (err) { + return err; + } + } + return ret; +} + IMPL(pselect6) { abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr; @@ -10649,114 +10769,6 @@ static abi_long do_syscall1(void *cpu_env, unsigned num, abi_long arg1, void *p; switch(num) { -#if defined(TARGET_NR_poll) || defined(TARGET_NR_ppoll) -# ifdef TARGET_NR_poll - case TARGET_NR_poll: -# endif -# ifdef TARGET_NR_ppoll - case TARGET_NR_ppoll: -# endif - { - struct target_pollfd *target_pfd; - unsigned int nfds = arg2; - struct pollfd *pfd; - unsigned int i; - - pfd = NULL; - target_pfd = NULL; - if (nfds) { - if (nfds > (INT_MAX / sizeof(struct target_pollfd))) { - return -TARGET_EINVAL; - } - - target_pfd = lock_user(VERIFY_WRITE, arg1, - sizeof(struct target_pollfd) * nfds, 1); - if (!target_pfd) { - return -TARGET_EFAULT; - } - - pfd = alloca(sizeof(struct pollfd) * nfds); - for (i = 0; i < nfds; i++) { - pfd[i].fd = tswap32(target_pfd[i].fd); - pfd[i].events = tswap16(target_pfd[i].events); - } - } - - switch (num) { -# ifdef TARGET_NR_ppoll - case TARGET_NR_ppoll: - { - struct timespec _timeout_ts, *timeout_ts = &_timeout_ts; - target_sigset_t *target_set; - sigset_t _set, *set = &_set; - - if (arg3) { - if (target_to_host_timespec(timeout_ts, arg3)) { - unlock_user(target_pfd, arg1, 0); - return -TARGET_EFAULT; - } - } else { - timeout_ts = NULL; - } - - if (arg4) { - if (arg5 != sizeof(target_sigset_t)) { - unlock_user(target_pfd, arg1, 0); - return -TARGET_EINVAL; - } - - target_set = lock_user(VERIFY_READ, arg4, sizeof(target_sigset_t), 1); - if (!target_set) { - unlock_user(target_pfd, arg1, 0); - return -TARGET_EFAULT; - } - target_to_host_sigset(set, target_set); - } else { - set = NULL; - } - - ret = get_errno(safe_ppoll(pfd, nfds, timeout_ts, - set, SIGSET_T_SIZE)); - - if (!is_error(ret) && arg3) { - host_to_target_timespec(arg3, timeout_ts); - } - if (arg4) { - unlock_user(target_set, arg4, 0); - } - return ret; - } -# endif -# ifdef TARGET_NR_poll - case TARGET_NR_poll: - { - struct timespec ts, *pts; - - if (arg3 >= 0) { - /* Convert ms to secs, ns */ - ts.tv_sec = arg3 / 1000; - ts.tv_nsec = (arg3 % 1000) * 1000000LL; - pts = &ts; - } else { - /* -ve poll() timeout means "infinite" */ - pts = NULL; - } - return get_errno(safe_ppoll(pfd, nfds, pts, NULL, 0)); - } -# endif - default: - g_assert_not_reached(); - } - - if (!is_error(ret)) { - for(i = 0; i < nfds; i++) { - target_pfd[i].revents = tswap16(pfd[i].revents); - } - } - unlock_user(target_pfd, arg1, sizeof(struct target_pollfd) * nfds); - } - return ret; -#endif case TARGET_NR_flock: /* NOTE: the flock constant seems to be the same for every Linux platform */ @@ -13060,6 +13072,10 @@ static impl_fn *syscall_table(unsigned num) SYSCALL(pipe); #endif SYSCALL(pipe2); +#ifdef TARGET_NR_poll + SYSCALL(poll); +#endif + SYSCALL(ppoll); SYSCALL(pselect6); SYSCALL(read); #ifdef TARGET_NR_readlink