]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge branch 'v4l_for_linus' into temp
authorMauro Carvalho Chehab <m.chehab@samsung.com>
Tue, 10 Dec 2013 07:43:02 +0000 (05:43 -0200)
committerMauro Carvalho Chehab <m.chehab@samsung.com>
Tue, 10 Dec 2013 07:43:02 +0000 (05:43 -0200)
* v4l_for_linus: (30 commits)
  [media] videobuf2-dma-sg: fix possible memory leak
  [media] vb2: regression fix: always set length field.
  [media] mt9p031: Include linux/of.h header
  [media] rtl2830: add parent for I2C adapter
  [media] media: marvell-ccic: use devm to release clk
  [media] ths7303: Declare as static a private function
  [media] em28xx-video: Swap release order to avoid lock nesting
  [media] usbtv: Add support for PAL video source
  [media] media_tree: Fix spelling errors
  [media] videobuf2: Add support for file access mode flags for DMABUF exporting
  [media] radio-shark2: Mark shark_resume_leds() inline to kill compiler warning
  [media] radio-shark: Mark shark_resume_leds() inline to kill compiler warning
  [media] af9035: unlock on error in af9035_i2c_master_xfer()
  [media] af9033: fix broken I2C
  [media] v4l: omap3isp: Don't check for missing get_fmt op on remote subdev
  [media] af9035: fix broken I2C and USB I/O
  [media] wm8775: fix broken audio routing
  [media] marvell-ccic: drop resource free in driver remove
  [media] tef6862/radio-tea5764: actually assign clamp result
  [media] cx231xx: use after free on error path in probe
  ...

1  2 
drivers/media/platform/omap3isp/ispvideo.c
drivers/media/v4l2-core/videobuf2-core.c
drivers/media/v4l2-core/videobuf2-dma-sg.c

index d86bb8cdadd842f54481788e60cc403ccd5bbb74,0d3a8ffe47a3c15efc27faef3712f682e6a7f620..c779f210d2c623e9807ad7c41737813ed92d43ea
@@@ -185,40 -178,9 +185,40 @@@ static void *vb2_dma_sg_get_userptr(voi
        buf->pages = kzalloc(buf->num_pages * sizeof(struct page *),
                             GFP_KERNEL);
        if (!buf->pages)
-               return NULL;
+               goto userptr_fail_alloc_pages;
  
 -      num_pages_from_user = get_user_pages(current, current->mm,
 +      vma = find_vma(current->mm, vaddr);
 +      if (!vma) {
 +              dprintk(1, "no vma for address %lu\n", vaddr);
 +              goto userptr_fail_find_vma;
 +      }
 +
 +      if (vma->vm_end < vaddr + size) {
 +              dprintk(1, "vma at %lu is too small for %lu bytes\n",
 +                      vaddr, size);
 +              goto userptr_fail_find_vma;
 +      }
 +
 +      buf->vma = vb2_get_vma(vma);
 +      if (!buf->vma) {
 +              dprintk(1, "failed to copy vma\n");
 +              goto userptr_fail_find_vma;
 +      }
 +
 +      if (vma_is_io(buf->vma)) {
 +              for (num_pages_from_user = 0;
 +                   num_pages_from_user < buf->num_pages;
 +                   ++num_pages_from_user, vaddr += PAGE_SIZE) {
 +                      unsigned long pfn;
 +
 +                      if (follow_pfn(buf->vma, vaddr, &pfn)) {
 +                              dprintk(1, "no page for address %lu\n", vaddr);
 +                              break;
 +                      }
 +                      buf->pages[num_pages_from_user] = pfn_to_page(pfn);
 +              }
 +      } else
 +              num_pages_from_user = get_user_pages(current, current->mm,
                                             vaddr & PAGE_MASK,
                                             buf->num_pages,
                                             write,
  userptr_fail_alloc_table_from_pages:
  userptr_fail_get_user_pages:
        dprintk(1, "get_user_pages requested/got: %d/%d]\n",
 -             num_pages_from_user, buf->num_pages);
 -      while (--num_pages_from_user >= 0)
 -              put_page(buf->pages[num_pages_from_user]);
 +              buf->num_pages, num_pages_from_user);
 +      if (!vma_is_io(buf->vma))
 +              while (--num_pages_from_user >= 0)
 +                      put_page(buf->pages[num_pages_from_user]);
 +      vb2_put_vma(buf->vma);
 +userptr_fail_find_vma:
        kfree(buf->pages);
+ userptr_fail_alloc_pages:
        kfree(buf);
        return NULL;
  }