From patchwork Thu May 6 04:06:21 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mauro Carvalho Chehab X-Patchwork-Id: 97263 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 o4646TfM008905 for ; Thu, 6 May 2010 04:06:30 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751552Ab0EFEGZ (ORCPT ); Thu, 6 May 2010 00:06:25 -0400 Received: from bombadil.infradead.org ([18.85.46.34]:45528 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751322Ab0EFEGY (ORCPT ); Thu, 6 May 2010 00:06:24 -0400 Received: from 201-68-231-100.dsl.telesp.net.br ([201.68.231.100] helo=[192.168.30.170]) by bombadil.infradead.org with esmtpsa (Exim 4.69 #1 (Red Hat Linux)) id 1O9sLv-00035u-Nw; Thu, 06 May 2010 04:06:24 +0000 Message-ID: <4BE2403D.3080601@infradead.org> Date: Thu, 06 May 2010 01:06:21 -0300 From: Mauro Carvalho Chehab User-Agent: Thunderbird 2.0.0.22 (X11/20090609) MIME-Version: 1.0 To: Arnout Vandecappelle CC: linux-media@vger.kernel.org Subject: Re: [PATCH 2/2] V4L/DVB: buf-dma-sg.c: support non-pageable user-allocated memory References: <1268866385-15692-1-git-send-email-arnout@mind.be> <1268866385-15692-3-git-send-email-arnout@mind.be> In-Reply-To: <1268866385-15692-3-git-send-email-arnout@mind.be> X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html 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, 06 May 2010 04:06:30 +0000 (UTC) --- work.orig/drivers/media/video/videobuf-dma-sg.c +++ work/drivers/media/video/videobuf-dma-sg.c @@ -145,6 +145,7 @@ static int videobuf_dma_init_user_locked { unsigned long first, last; int err, rw = 0; + struct vm_area_struct *vma; dma->direction = direction; switch (dma->direction) { @@ -162,6 +163,25 @@ static int videobuf_dma_init_user_locked 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"); + /* same error that get_user_pages() would give */ + return -EFAULT; + } + 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%llx]\n", + data, size, dma->nr_pages, (long long)dma->bus_addr); + return 0; + } + dma->pages = kmalloc(dma->nr_pages * sizeof(struct page *), GFP_KERNEL); if (NULL == dma->pages) return -ENOMEM;