From patchwork Tue Mar 17 11:56:34 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 28823 X-Patchwork-Delegate: hverkuil@xs4all.nl Received: from mail.tu-berlin.de ([130.149.7.33]) by www.linuxtv.org with esmtp (Exim 4.72) (envelope-from ) id 1YXq7S-0002W8-0J; Tue, 17 Mar 2015 12:57:10 +0100 X-tubIT-Incoming-IP: 209.132.180.67 Received: from vger.kernel.org ([209.132.180.67]) by mail.tu-berlin.de (exim-4.76/mailfrontend-8) with esmtp id 1YXq7P-0006dj-mF; Tue, 17 Mar 2015 12:57:09 +0100 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752959AbbCQL5F (ORCPT + 1 other); Tue, 17 Mar 2015 07:57:05 -0400 Received: from cantor2.suse.de ([195.135.220.15]:43214 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753866AbbCQL47 (ORCPT ); Tue, 17 Mar 2015 07:56:59 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 9D292ACAA; Tue, 17 Mar 2015 11:56:57 +0000 (UTC) Received: by quack.suse.cz (Postfix, from userid 1000) id 5663681C76; Tue, 17 Mar 2015 12:56:53 +0100 (CET) From: Jan Kara To: linux-media@vger.kernel.org Cc: Hans Verkuil , Mauro Carvalho Chehab , linux-mm@kvack.org, dri-devel@lists.freedesktop.org, David Airlie , Jan Kara Subject: [PATCH 4/9] vb2: Provide helpers for mapping virtual addresses Date: Tue, 17 Mar 2015 12:56:34 +0100 Message-Id: <1426593399-6549-5-git-send-email-jack@suse.cz> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1426593399-6549-1-git-send-email-jack@suse.cz> References: <1426593399-6549-1-git-send-email-jack@suse.cz> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-PMX-Version: 6.0.0.2142326, Antispam-Engine: 2.7.2.2107409, Antispam-Data: 2015.3.17.115125 X-PMX-Spam: Gauge=IIIIIIII, Probability=8%, Report=' MULTIPLE_RCPTS 0.1, HTML_00_01 0.05, HTML_00_10 0.05, BODY_SIZE_3000_3999 0, BODY_SIZE_5000_LESS 0, BODY_SIZE_7000_LESS 0, REFERENCES 0, URI_ENDS_IN_HTML 0, __ANY_URI 0, __CP_URI_IN_BODY 0, __HAS_FROM 0, __HAS_MSGID 0, __HAS_X_MAILER 0, __HAS_X_MAILING_LIST 0, __IN_REP_TO 0, __MIME_TEXT_ONLY 0, __MULTIPLE_RCPTS_CC_X2 0, __REFERENCES 0, __SANE_MSGID 0, __SUBJ_ALPHA_END 0, __TO_MALFORMED_2 0, __TO_NO_NAME 0, __URI_NO_WWW 0, __URI_NS ' Provide simple helper functions to map virtual address range into an array of pfns. Signed-off-by: Jan Kara --- drivers/media/v4l2-core/videobuf2-memops.c | 57 ++++++++++++++++++++++++++++++ include/media/videobuf2-memops.h | 4 +++ 2 files changed, 61 insertions(+) diff --git a/drivers/media/v4l2-core/videobuf2-memops.c b/drivers/media/v4l2-core/videobuf2-memops.c index 81c1ad8b2cf1..80ade22b920c 100644 --- a/drivers/media/v4l2-core/videobuf2-memops.c +++ b/drivers/media/v4l2-core/videobuf2-memops.c @@ -137,6 +137,63 @@ int vb2_get_contig_userptr(unsigned long vaddr, unsigned long size, EXPORT_SYMBOL_GPL(vb2_get_contig_userptr); /** + * vb2_create_pfnvec() - map virtual addresses to pfns + * @start: Virtual user address where we start mapping + * @length: Length of a range to map + * @write: Should we map for writing into the area + * + * This function allocates and fills in a vector with pfns corresponding to + * virtual address range passed in arguments. If pfns have corresponding pages, + * page references are also grabbed to pin pages in memory. The function + * returns pointer to the vector on success and error pointer in case of + * failure. Returned vector needs to be freed via vb2_destroy_pfnvec(). + */ +struct pinned_pfns *vb2_create_pfnvec(unsigned long start, unsigned long length, + bool write) +{ + int ret; + unsigned long first, last; + unsigned long nr; + struct pinned_pfns *pfns; + + first = start >> PAGE_SHIFT; + last = (start + length - 1) >> PAGE_SHIFT; + nr = last - first + 1; + pfns = pfns_vector_create(nr); + if (!pfns) + return ERR_PTR(-ENOMEM); + ret = get_vaddr_pfns(start, nr, write, 1, pfns); + if (ret < 0) + goto out_destroy; + /* We accept only complete set of PFNs */ + if (ret != nr) { + ret = -EFAULT; + goto out_release; + } + return pfns; +out_release: + put_vaddr_pfns(pfns); +out_destroy: + pfns_vector_destroy(pfns); + return ERR_PTR(ret); +} +EXPORT_SYMBOL(vb2_create_pfnvec); + +/** + * vb2_destroy_pfnvec() - release vector of mapped pfns + * @pfns: vector of pfns to release + * + * This releases references to all pages in the vector @pfns (if corresponding + * pfns are backed by pages) and frees the passed vector. + */ +void vb2_destroy_pfnvec(struct pinned_pfns *pfns) +{ + put_vaddr_pfns(pfns); + pfns_vector_destroy(pfns); +} +EXPORT_SYMBOL(vb2_destroy_pfnvec); + +/** * vb2_common_vm_open() - increase refcount of the vma * @vma: virtual memory region for the mapping * diff --git a/include/media/videobuf2-memops.h b/include/media/videobuf2-memops.h index f05444ca8c0c..868f9c1cd92d 100644 --- a/include/media/videobuf2-memops.h +++ b/include/media/videobuf2-memops.h @@ -15,6 +15,7 @@ #define _MEDIA_VIDEOBUF2_MEMOPS_H #include +#include /** * vb2_vmarea_handler - common vma refcount tracking handler @@ -36,5 +37,8 @@ int vb2_get_contig_userptr(unsigned long vaddr, unsigned long size, struct vm_area_struct *vb2_get_vma(struct vm_area_struct *vma); void vb2_put_vma(struct vm_area_struct *vma); +struct pinned_pfns *vb2_create_pfnvec(unsigned long start, unsigned long length, + bool write); +void vb2_destroy_pfnvec(struct pinned_pfns *pfns); #endif