From patchwork Wed Jun 19 12:56:46 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 17994 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-gh0-f198.google.com (mail-gh0-f198.google.com [209.85.160.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id B11BA2397B for ; Wed, 19 Jun 2013 12:57:21 +0000 (UTC) Received: by mail-gh0-f198.google.com with SMTP id r13sf4209831ghr.9 for ; Wed, 19 Jun 2013 05:57:21 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-beenthere:x-forwarded-to:x-forwarded-for:delivered-to:x-auditid :from:to:date:message-id:x-mailer:x-brightmail-tracker:cc:subject :x-beenthere:x-mailman-version:precedence:list-id:list-unsubscribe :list-archive:list-post:list-help:list-subscribe:mime-version :errors-to:sender:x-gm-message-state:x-original-sender :x-original-authentication-results:mailing-list:x-google-group-id :content-type:content-transfer-encoding; bh=AewXfyYYZcCJ1T7A+3d4XrdeXv2seAlEIpglpYm62iQ=; b=dkkTxxGW2m5O00sIhqe/aM894LIQsxeALJxHc0mD/Tx9D5P2xtIMtzIuatFsnEWS2y sZLj1nMoZAMNFhYSyWtl0XRbqze38ffibTl5Fq42iPDwoafchSUk42fWApEvzoDr2BQ0 R0FBNQ39j5nrkTek3HsnlsPMbTJKwvXvsFWsUGi1fuuffz/3JH5ZgufjBuzC0InmlkS4 iWUhE4nt+DFbNDdwgohEd8r+W+3wIQAI3G4BzjtzqivzHrNfv41P1gyyGrM+08Nyo1ke 67Nj4ARf4mwL71WmWELl8ZEK20AwgBKlwJB+ogkn99wdSxaeW4Cp96A5o1L7AYS+vFYy vu3g== X-Received: by 10.224.59.205 with SMTP id m13mr3391875qah.7.1371646641369; Wed, 19 Jun 2013 05:57:21 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.74.169 with SMTP id u9ls280185qev.32.gmail; Wed, 19 Jun 2013 05:57:21 -0700 (PDT) X-Received: by 10.52.163.67 with SMTP id yg3mr779780vdb.14.1371646641176; Wed, 19 Jun 2013 05:57:21 -0700 (PDT) Received: from mail-ve0-x22e.google.com (mail-ve0-x22e.google.com [2607:f8b0:400c:c01::22e]) by mx.google.com with ESMTPS id ff9si6485436vcb.37.2013.06.19.05.57.21 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 19 Jun 2013 05:57:21 -0700 (PDT) Received-SPF: neutral (google.com: 2607:f8b0:400c:c01::22e is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=2607:f8b0:400c:c01::22e; Received: by mail-ve0-f174.google.com with SMTP id oz10so3982476veb.19 for ; Wed, 19 Jun 2013 05:57:21 -0700 (PDT) X-Received: by 10.220.67.10 with SMTP id p10mr572548vci.85.1371646641007; Wed, 19 Jun 2013 05:57:21 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.58.165.8 with SMTP id yu8csp107770veb; Wed, 19 Jun 2013 05:57:20 -0700 (PDT) X-Received: by 10.15.41.196 with SMTP id s44mr2543461eev.138.1371646639383; Wed, 19 Jun 2013 05:57:19 -0700 (PDT) Received: from ip-10-141-164-156.ec2.internal (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTPS id o46si19166896eef.335.2013.06.19.05.57.18 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Wed, 19 Jun 2013 05:57:19 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linaro-mm-sig-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Received: from localhost ([127.0.0.1] helo=ip-10-141-164-156.ec2.internal) by ip-10-141-164-156.ec2.internal with esmtp (Exim 4.76) (envelope-from ) id 1UpHwk-0006ug-SY; Wed, 19 Jun 2013 12:57:10 +0000 Received: from mailout4.samsung.com ([203.254.224.34]) by ip-10-141-164-156.ec2.internal with esmtp (Exim 4.76) (envelope-from ) id 1UpHwi-0006ub-Un for linaro-mm-sig@lists.linaro.org; Wed, 19 Jun 2013 12:57:09 +0000 Received: from epcpsbgm2.samsung.com (epcpsbgm2 [203.254.230.27]) by mailout4.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MON002O85B3HME0@mailout4.samsung.com> for linaro-mm-sig@lists.linaro.org; Wed, 19 Jun 2013 21:57:07 +0900 (KST) X-AuditID: cbfee61b-b7f8e6d00000524c-95-51c1aaa3a9b6 Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id 10.3A.21068.3AAA1C15; Wed, 19 Jun 2013 21:57:07 +0900 (KST) Received: from localhost.localdomain ([106.116.147.30]) by mmp2.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0MON009B55AZX970@mmp2.samsung.com>; Wed, 19 Jun 2013 21:57:07 +0900 (KST) From: Marek Szyprowski To: linux-media@vger.kernel.org, linaro-mm-sig@lists.linaro.org Date: Wed, 19 Jun 2013 14:56:46 +0200 Message-id: <1371646607-23321-1-git-send-email-m.szyprowski@samsung.com> X-Mailer: git-send-email 1.7.9.5 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmphluLIzCtJLcpLzFFi42I5/e+xoO7iVQcDDX6s1bb48foCm8XZpjfs Fl+uPGSy6NmwldVi7f3bbBZrj9xltzj8pp3V4uSfXkaLee0vWR04PXbOusvucefaHjaP2/8e M3v0bVnF6PF5k1wAaxSXTUpqTmZZapG+XQJXRntPL1vBGeWKncebmBsYm2S7GDk5JARMJBon HWOCsMUkLtxbz9bFyMUhJDCdUWLdvBYmCKedSWLLt03MIFVsAoYSXW+72EBsEQF7iTVvDzKC 2MwCU5gkTh0JALGFBZIlFlzYClbPIqAq0f34AFA9BwevgIfErndBIKaEgILEnEk2Exi5FzAy rGIUTS1ILihOSs810itOzC0uzUvXS87P3cQIDptn0jsYVzVYHGIU4GBU4uF1mHswUIg1say4 MvcQowQHs5IIb8VMoBBvSmJlVWpRfnxRaU5q8SFGaQ4WJXHeg63WgUIC6YklqdmpqQWpRTBZ Jg5OqQbGupKIc9Ny9y3YXV2Vv8k1taB5YvnPfrMzmonbb1x6Ivx7X3DknLZmKRZNddU02RWx Op8WXNn3oEusf0Fk8hH9c8bvP0/3u/zd/sX7xusr/un67DtYbDrJesdLy7iNyTPycp8byPPP YX7wLoRTlP1o+BNht+UN2UzB3z+7vGiWOZplmfot9cYeJZbijERDLeai4kQA96NSdxcCAAA= Cc: Kamil Debski , Kyungmin Park , Sylwester Nawrocki , lonsn2005@gmail.com Subject: [Linaro-mm-sig] [PATCH] v4l2: videobuf2-dc: fix support for mappings without struct page in userptr mode X-BeenThere: linaro-mm-sig@lists.linaro.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Errors-To: linaro-mm-sig-bounces@lists.linaro.org Sender: linaro-mm-sig-bounces@lists.linaro.org X-Gm-Message-State: ALoCoQlP9vLnepleMPSaAj7Ww5cPgyPBWDbps7INUwJxwtWaG3lDpYpttrJDugNpKQNnsxx6W5+k X-Original-Sender: m.szyprowski@samsung.com X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 2607:f8b0:400c:c01::22e 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 Earlier version of dma-contig allocator in user ptr mode assumed that in all cases DMA address equals physical address. This was just a special case. Commit e15dab752d4c588544ccabdbe020a7cc092e23c8 introduced correct support for converting userpage to dma address, but unfortunately it broke the support for simple dma address = physical address for the case, when given physical frame has no struct page associated with it (this happens if one use for example dma_declare_coherent api or other reserved memory approach). This commit restores support for such cases. Signed-off-by: Marek Szyprowski --- drivers/media/v4l2-core/videobuf2-dma-contig.c | 87 ++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 5 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c index fd56f25..1382749 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c @@ -423,6 +423,39 @@ static inline int vma_is_io(struct vm_area_struct *vma) return !!(vma->vm_flags & (VM_IO | VM_PFNMAP)); } +static int vb2_dc_get_user_pfn(unsigned long start, int n_pages, + struct vm_area_struct *vma, unsigned long *res) +{ + unsigned long pfn, start_pfn, prev_pfn; + unsigned int i; + int ret; + + if (!vma_is_io(vma)) + return -EFAULT; + + ret = follow_pfn(vma, start, &pfn); + if (ret) + return ret; + + start_pfn = pfn; + start += PAGE_SIZE; + + for (i = 1; i < n_pages; ++i, start += PAGE_SIZE) { + prev_pfn = pfn; + ret = follow_pfn(vma, start, &pfn); + + if (ret) { + pr_err("no page for address %lu\n", start); + return ret; + } + if (pfn != prev_pfn + 1) + return -EINVAL; + } + + *res = start_pfn; + return 0; +} + static int vb2_dc_get_user_pages(unsigned long start, struct page **pages, int n_pages, struct vm_area_struct *vma, int write) { @@ -433,6 +466,9 @@ static int vb2_dc_get_user_pages(unsigned long start, struct page **pages, unsigned long pfn; int ret = follow_pfn(vma, start, &pfn); + if (!pfn_valid(pfn)) + return -EINVAL; + if (ret) { pr_err("no page for address %lu\n", start); return ret; @@ -468,16 +504,49 @@ static void vb2_dc_put_userptr(void *buf_priv) struct vb2_dc_buf *buf = buf_priv; struct sg_table *sgt = buf->dma_sgt; - dma_unmap_sg(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir); - if (!vma_is_io(buf->vma)) - vb2_dc_sgt_foreach_page(sgt, vb2_dc_put_dirty_page); + if (sgt) { + dma_unmap_sg(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir); + if (!vma_is_io(buf->vma)) + vb2_dc_sgt_foreach_page(sgt, vb2_dc_put_dirty_page); - sg_free_table(sgt); - kfree(sgt); + sg_free_table(sgt); + kfree(sgt); + } vb2_put_vma(buf->vma); kfree(buf); } +/* + * For some kind of reserved memory there might be no struct page available, + * so all that can be done to support such 'pages' is to try to convert + * pfn to dma address or at the last resort just assume that + * dma address == physical address (like it has been assumed in earlier version + * of videobuf2-dma-contig + */ + +#ifdef __arch_pfn_to_dma +static inline dma_addr_t vb2_dc_pfn_to_dma(struct device *dev, unsigned long pfn) +{ + return (dma_addr_t)__arch_pfn_to_dma(dev, pfn); +} +#elsif defined(__pfn_to_bus) +static inline dma_addr_t vb2_dc_pfn_to_dma(struct device *dev, unsigned long pfn) +{ + return (dma_addr_t)__pfn_to_bus(pfn); +} +#elsif defined(__pfn_to_phys) +static inline dma_addr_t vb2_dc_pfn_to_dma(struct device *dev, unsigned long pfn) +{ + return (dma_addr_t)__pfn_to_phys(pfn); +} +#else +static inline dma_addr_t vb2_dc_pfn_to_dma(struct device *dev, unsigned long pfn) +{ + /* really, we cannot do anything better at this point */ + return (dma_addr_t)(pfn) << PAGE_SHIFT; +} +#endif + static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, unsigned long size, int write) { @@ -548,6 +617,14 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr, /* extract page list from userspace mapping */ ret = vb2_dc_get_user_pages(start, pages, n_pages, vma, write); if (ret) { + unsigned long pfn; + if (vb2_dc_get_user_pfn(start, n_pages, vma, &pfn) == 0) { + buf->dma_addr = vb2_dc_pfn_to_dma(buf->dev, pfn); + buf->size = size; + kfree(pages); + return buf; + } + pr_err("failed to get user pages\n"); goto fail_vma; }