From patchwork Mon Feb 2 04:06:24 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Nicholas A. Bellinger" X-Patchwork-Id: 5759201 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id CEDAC9F302 for ; Mon, 2 Feb 2015 04:40:28 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E36442026F for ; Mon, 2 Feb 2015 04:40:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0290E20266 for ; Mon, 2 Feb 2015 04:40:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932215AbbBBEjl (ORCPT ); Sun, 1 Feb 2015 23:39:41 -0500 Received: from mail-oi0-f44.google.com ([209.85.218.44]:41040 "EHLO mail-oi0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754773AbbBBEjc (ORCPT ); Sun, 1 Feb 2015 23:39:32 -0500 Received: by mail-oi0-f44.google.com with SMTP id a3so42477561oib.3 for ; Sun, 01 Feb 2015 20:39:32 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=R9Fdiv7iSyvtxLtQ2vYuEQzcEXNl0Eyxfsaf6cgneEI=; b=QxYtWv7XG7F5Dhe1DM6tXhxyLIC4YbWAMNYKfFvoSzfuN+W7W4Y+VU9JFbpxvPvVXf zwoSuTRsNUFyABjkJywXLPbXUayby3MyfUXB2sWZ21QNPoyrheOm5LDR6HGBlfjNu3a3 JULGHMYGN667ySzBhp1krbWfB6mSTalRtHhIw1nREbDiHV4uhqj0ij+0WmC9QhsL2W5n WDrbevYUf5GZfM3dh8uIHTPqSzVpZBeYPBwOhp27+PkObThvPOMKsB4gQQKdUgFa9iWN FBbe9uow17WH2+KmctNMHnFgLw5U0rwsHjJBVDD7WXcmkKWly59kJgCnWgs5co+RYQRD xDhg== X-Gm-Message-State: ALoCoQm5/GX87D2kPs6o4VcGb7bpfntefctWtla4dVaIph1eBCQ0sn6v601XJAqJpraPgBSf1f4j X-Received: by 10.182.247.99 with SMTP id yd3mr11015001obc.24.1422851972253; Sun, 01 Feb 2015 20:39:32 -0800 (PST) Received: from localhost.localdomain (mail.linux-iscsi.org. [67.23.28.174]) by mx.google.com with ESMTPSA id y2sm8950007oei.1.2015.02.01.20.39.31 (version=TLSv1 cipher=RC4-SHA bits=128/128); Sun, 01 Feb 2015 20:39:31 -0800 (PST) From: "Nicholas A. Bellinger" To: target-devel Cc: linux-scsi , kvm-devel , Paolo Bonzini , "Michael S. Tsirkin" , Nicholas Bellinger Subject: [PATCH-v2 01/11] lib/iovec: Add memcpy_fromiovec_out library function Date: Mon, 2 Feb 2015 04:06:24 +0000 Message-Id: <1422849994-3419-2-git-send-email-nab@daterainc.com> X-Mailer: git-send-email 1.7.2.5 In-Reply-To: <1422849994-3419-1-git-send-email-nab@daterainc.com> References: <1422849994-3419-1-git-send-email-nab@daterainc.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Nicholas Bellinger This patch adds a new memcpy_fromiovec_out() library function which modifies the passed *iov following memcpy_fromiovec(), but also returns the next current iovec pointer via **iov_out. This is useful for vhost ANY_LAYOUT support when guests are allowed to generate incoming virtio request headers combined with subsequent SGL payloads into a single iovec. Cc: Michael S. Tsirkin Cc: Paolo Bonzini Signed-off-by: Nicholas Bellinger --- include/linux/uio.h | 2 ++ lib/iovec.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/include/linux/uio.h b/include/linux/uio.h index 1c5e453..3e4473d 100644 --- a/include/linux/uio.h +++ b/include/linux/uio.h @@ -136,6 +136,8 @@ size_t csum_and_copy_to_iter(void *addr, size_t bytes, __wsum *csum, struct iov_ size_t csum_and_copy_from_iter(void *addr, size_t bytes, __wsum *csum, struct iov_iter *i); int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len); +int memcpy_fromiovec_out(unsigned char *kdata, struct iovec *iov, + struct iovec **iov_out, int len); int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov, int offset, int len); int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata, diff --git a/lib/iovec.c b/lib/iovec.c index 2d99cb4..24c8148 100644 --- a/lib/iovec.c +++ b/lib/iovec.c @@ -28,6 +28,41 @@ int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len) EXPORT_SYMBOL(memcpy_fromiovec); /* + * Copy iovec to kernel, modifying the passed *iov entries. + * + * Save **iov_out for the caller to use upon return, that may either + * contain the current entry with a re-calculated iov_base + iov_len + * or next unmodified entry. + * + * Also note that any iovec entries preceeding the final *iov_out are + * zeroed by copy_from_user(). + * + * Returns -EFAULT on error. + */ + +int memcpy_fromiovec_out(unsigned char *kdata, struct iovec *iov, + struct iovec **iov_out, int len) +{ + while (len > 0) { + if (iov->iov_len) { + int copy = min_t(unsigned int, len, iov->iov_len); + if (copy_from_user(kdata, iov->iov_base, copy)) + return -EFAULT; + len -= copy; + kdata += copy; + iov->iov_base += copy; + iov->iov_len -= copy; + } + if (!iov->iov_len) + iov++; + } + *iov_out = iov; + + return 0; +} +EXPORT_SYMBOL(memcpy_fromiovec_out); + +/* * Copy kernel to iovec. Returns -EFAULT on error. */