From patchwork Mon Mar 10 12:22:57 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Riku Voipio X-Patchwork-Id: 25963 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-qc0-f200.google.com (mail-qc0-f200.google.com [209.85.216.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 946D22055F for ; Mon, 10 Mar 2014 12:27:22 +0000 (UTC) Received: by mail-qc0-f200.google.com with SMTP id i17sf17365193qcy.11 for ; Mon, 10 Mar 2014 05:27:22 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:date :message-id:in-reply-to:references:cc:subject:precedence:list-id :list-unsubscribe:list-archive:list-post:list-help:list-subscribe :errors-to:sender:x-original-sender :x-original-authentication-results:mailing-list; bh=QNhW54jRO1beNa+wCFpDIND8ZlvMQF8RdiqbF2Z/Swo=; b=F5+nFxHdOvHUSOZoUOVmWaz3DLCtuMlsgk8mnC/nhCBeLGADM/99U4RWIqBzkV7TEt h81MTaeFd/QIH15/BOu7iFntqzkRZxgLOJQn4QMHi6so7kpZMHLUVUwmfahb/8KsdwKh nHmqm8FAAdc0/aBpb7bjCRKCBYn60fVXnN3iSgKgse23l1X9IYxfCNVEHNIlT/zZmJSM e/sUMWrpL6KZlt9MYBbgv6y7SLK8KQQQBMFrKuyy76yebWdEBlBZ8sFB0uNQJ0yWDRsc DYhOcrUMerZ0ANQKA4logDiX8zYT4nweFUKYZLH2Y41oc/VQQb52MevMGZ4Q6lEjv3mM Nc9g== X-Gm-Message-State: ALoCoQmd92fe5JHWVKenSpWa3CBkUdgBYTIbUXFpQ323ZmC0NVB/X+TnYnDG/Vd0dNSHrUmoFCMR X-Received: by 10.58.59.104 with SMTP id y8mr1889655veq.18.1394454442348; Mon, 10 Mar 2014 05:27:22 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.35.208 with SMTP id n74ls2041317qgn.65.gmail; Mon, 10 Mar 2014 05:27:22 -0700 (PDT) X-Received: by 10.58.190.99 with SMTP id gp3mr80434vec.32.1394454442197; Mon, 10 Mar 2014 05:27:22 -0700 (PDT) Received: from mail-vc0-f175.google.com (mail-vc0-f175.google.com [209.85.220.175]) by mx.google.com with ESMTPS id e10si4637641vcn.16.2014.03.10.05.27.22 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 10 Mar 2014 05:27:22 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.220.175 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.175; Received: by mail-vc0-f175.google.com with SMTP id lh14so4819646vcb.20 for ; Mon, 10 Mar 2014 05:27:22 -0700 (PDT) X-Received: by 10.58.200.229 with SMTP id jv5mr22247228vec.15.1394454442079; Mon, 10 Mar 2014 05:27:22 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.220.78.9 with SMTP id i9csp114811vck; Mon, 10 Mar 2014 05:27:21 -0700 (PDT) X-Received: by 10.140.81.244 with SMTP id f107mr1643731qgd.104.1394454441587; Mon, 10 Mar 2014 05:27:21 -0700 (PDT) Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id s10si8687684qas.3.2014.03.10.05.27.21 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Mon, 10 Mar 2014 05:27:21 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Received: from localhost ([::1]:48428 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WMzIf-0002M3-41 for patch@linaro.org; Mon, 10 Mar 2014 08:27:21 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41913) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WMzEc-0002or-LB for qemu-devel@nongnu.org; Mon, 10 Mar 2014 08:23:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WMzEW-00084u-2P for qemu-devel@nongnu.org; Mon, 10 Mar 2014 08:23:10 -0400 Received: from afflict.kos.to ([92.243.29.197]:50048) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WMzEV-00084R-GD for qemu-devel@nongnu.org; Mon, 10 Mar 2014 08:23:04 -0400 Received: from localhost.localdomain (afflict [92.243.29.197]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by afflict.kos.to (Postfix) with ESMTPSA id CBAEB26565; Mon, 10 Mar 2014 13:23:01 +0100 (CET) From: riku.voipio@linaro.org To: qemu-devel@nongnu.org Date: Mon, 10 Mar 2014 14:22:57 +0200 Message-Id: X-Mailer: git-send-email 1.7.2.5 In-Reply-To: References: X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 92.243.29.197 Cc: peter.maydell@linaro.org, Alexander Graf Subject: [Qemu-devel] [PATCH 5/8] linux-user: Implement sendmmsg syscall X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: riku.voipio@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.175 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 From: Alexander Graf Glibc when built for newer kernels assumes that the sendmmsg syscall is available. Without it, dns resolution simply fails to work. Wrap the syscall with existing infrastructure so that we don't have a host dependency on sendmmsg. To avoid locking the same area of guest memory twice (which will break if DEBUG_REMAP is defined) we pull the lock/unlock part of do_sendrecvmsg() out into its own function so the actual implementation can be shared. Signed-off-by: Alexander Graf [PMM: add recvmmsg support; handle errors (which also implies support for non-blocking operations); cap the vector length as the kernel implementation does; don't lock guest memory twice; support MSG_WAITFORONE flag] Signed-off-by: Peter Maydell Signed-off-by: Riku Voipio Reviewed-by: Richard Henderson --- linux-user/syscall.c | 86 +++++++++++++++++++++++++++++++++++++++++------ linux-user/syscall_defs.h | 4 +++ 2 files changed, 80 insertions(+), 10 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index ccdbc4e..1f64867 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -1904,23 +1904,16 @@ static abi_long do_connect(int sockfd, abi_ulong target_addr, return get_errno(connect(sockfd, addr, addrlen)); } -/* do_sendrecvmsg() Must return target values and target errnos. */ -static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg, - int flags, int send) +/* do_sendrecvmsg_locked() Must return target values and target errnos. */ +static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp, + int flags, int send) { abi_long ret, len; - struct target_msghdr *msgp; struct msghdr msg; int count; struct iovec *vec; abi_ulong target_vec; - /* FIXME */ - if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE, - msgp, - target_msg, - send ? 1 : 0)) - return -TARGET_EFAULT; if (msgp->msg_name) { msg.msg_namelen = tswap32(msgp->msg_namelen); msg.msg_name = alloca(msg.msg_namelen); @@ -1975,10 +1968,75 @@ static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg, out: unlock_iovec(vec, target_vec, count, !send); out2: + return ret; +} + +static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg, + int flags, int send) +{ + abi_long ret; + struct target_msghdr *msgp; + + if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE, + msgp, + target_msg, + send ? 1 : 0)) { + return -TARGET_EFAULT; + } + ret = do_sendrecvmsg_locked(fd, msgp, flags, send); unlock_user_struct(msgp, target_msg, send ? 0 : 1); return ret; } +#ifdef TARGET_NR_sendmmsg +/* We don't rely on the C library to have sendmmsg/recvmmsg support, + * so it might not have this *mmsg-specific flag either. + */ +#ifndef MSG_WAITFORONE +#define MSG_WAITFORONE 0x10000 +#endif + +static abi_long do_sendrecvmmsg(int fd, abi_ulong target_msgvec, + unsigned int vlen, unsigned int flags, + int send) +{ + struct target_mmsghdr *mmsgp; + abi_long ret = 0; + int i; + + if (vlen > UIO_MAXIOV) { + vlen = UIO_MAXIOV; + } + + mmsgp = lock_user(VERIFY_WRITE, target_msgvec, sizeof(*mmsgp) * vlen, 1); + if (!mmsgp) { + return -TARGET_EFAULT; + } + + for (i = 0; i < vlen; i++) { + ret = do_sendrecvmsg_locked(fd, &mmsgp[i].msg_hdr, flags, send); + if (is_error(ret)) { + break; + } + mmsgp[i].msg_len = tswap32(ret); + /* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */ + if (flags & MSG_WAITFORONE) { + flags |= MSG_DONTWAIT; + } + } + + unlock_user(mmsgp, target_msgvec, sizeof(*mmsgp) * i); + + /* Return number of datagrams sent if we sent any at all; + * otherwise return the error. + */ + if (i) { + return i; + } + return ret; +} +#endif + /* If we don't have a system accept4() then just call accept. * The callsites to do_accept4() will ensure that they don't * pass a non-zero flags argument in this config. @@ -6716,6 +6774,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ret = do_sendrecvmsg(arg1, arg2, arg3, 1); break; #endif +#ifdef TARGET_NR_sendmmsg + case TARGET_NR_sendmmsg: + ret = do_sendrecvmmsg(arg1, arg2, arg3, arg4, 1); + break; + case TARGET_NR_recvmmsg: + ret = do_sendrecvmmsg(arg1, arg2, arg3, arg4, 0); + break; +#endif #ifdef TARGET_NR_sendto case TARGET_NR_sendto: ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6); diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index d55f396..732c9e3 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -240,6 +240,10 @@ __target_cmsg_nxthdr (struct target_msghdr *__mhdr, struct target_cmsghdr *__cms return __cmsg; } +struct target_mmsghdr { + struct target_msghdr msg_hdr; /* Message header */ + unsigned int msg_len; /* Number of bytes transmitted */ +}; struct target_rusage { struct target_timeval ru_utime; /* user time used */