From patchwork Thu Mar 4 16:00:51 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnout Vandecappelle X-Patchwork-Id: 83627 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o24G1e1p007299 for ; Thu, 4 Mar 2010 16:01:40 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752018Ab0CDQBj (ORCPT ); Thu, 4 Mar 2010 11:01:39 -0500 Received: from 132.79-246-81.adsl-static.isp.belgacom.be ([81.246.79.132]:51466 "EHLO viper.mind.be" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751755Ab0CDQBi (ORCPT ); Thu, 4 Mar 2010 11:01:38 -0500 Received: from [10.3.4.27] (helo=localhost.localdomain) by viper.mind.be with esmtp (Exim 4.69) (envelope-from ) id 1NnDUW-0000tk-4n; Thu, 04 Mar 2010 17:01:36 +0100 From: Arnout Vandecappelle To: linux-media@vger.kernel.org, Sakari Ailus , mchehab@infradead.org Cc: Arnout Vandecappelle Subject: [PATCH 2/2] V4L/DVB: buf-dma-sg.c: support non-pageable user-allocated memory Date: Thu, 4 Mar 2010 17:00:51 +0100 Message-Id: <1267718451-24961-3-git-send-email-arnout@mind.be> X-Mailer: git-send-email 1.6.3.3 In-Reply-To: <201003031512.45428.arnout@mind.be> References: <201003031512.45428.arnout@mind.be> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Thu, 04 Mar 2010 16:01:40 +0000 (UTC) diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c index 3b6f1b8..7884207 100644 --- a/drivers/media/video/videobuf-dma-sg.c +++ b/drivers/media/video/videobuf-dma-sg.c @@ -136,6 +136,7 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma, { unsigned long first,last; int err, rw = 0; + struct vm_area_struct *vma; dma->direction = direction; switch (dma->direction) { @@ -153,6 +154,23 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma, last = ((data+size-1) & PAGE_MASK) >> PAGE_SHIFT; dma->offset = data & ~PAGE_MASK; dma->nr_pages = last-first+1; + + /* In case the buffer is user-allocated and is actually an IO buffer for + some other hardware, we cannot map pages for it. It in fact behaves + the same as an overlay. */ + vma = find_vma (current->mm, data); + if (vma && (vma->vm_flags & VM_IO)) { + /* Only a single contiguous buffer is supported. */ + if (vma->vm_end < data + size) { + dprintk(1, "init user: non-contiguous IO buffer.\n"); + return -EFAULT; /* same error that get_user_pages() would give */ + } + dma->bus_addr = (vma->vm_pgoff << PAGE_SHIFT) + (data - vma->vm_start); + dprintk(1,"init user IO [0x%lx+0x%lx => %d pages at 0x%x]\n", + data, size, dma->nr_pages, dma->bus_addr); + return 0; + } + dma->pages = kmalloc(dma->nr_pages * sizeof(struct page*), GFP_KERNEL); if (NULL == dma->pages)