diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-10-29 13:21:34 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-11-12 22:05:33 -0500 |
commit | c79c7ad9d1398787f907f85afc44cf7d6623027d (patch) | |
tree | 986368272d5a595ae5214bf91f05ae31503b7c5a | |
parent | f1e65e494c7914220ac6d87caa126114f46ac462 (diff) |
Fix a few incorrectly checked [io_]remap_pfn_range() calls
commit 7314e613d5ff9f0934f7a0f74ed7973b903315d1 upstream.
Nico Golde reports a few straggling uses of [io_]remap_pfn_range() that
really should use the vm_iomap_memory() helper. This trivially converts
two of them to the helper, and comments about why the third one really
needs to continue to use remap_pfn_range(), and adds the missing size
check.
Reported-by: Nico Golde <nico@ngolde.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/uio/uio.c | 17 | ||||
-rw-r--r-- | drivers/video/au1100fb.c | 26 | ||||
-rw-r--r-- | drivers/video/au1200fb.c | 23 |
3 files changed, 17 insertions, 49 deletions
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index bcdcb4c2132c..2d57a00dc173 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c | |||
@@ -654,16 +654,29 @@ static int uio_mmap_physical(struct vm_area_struct *vma) | |||
654 | { | 654 | { |
655 | struct uio_device *idev = vma->vm_private_data; | 655 | struct uio_device *idev = vma->vm_private_data; |
656 | int mi = uio_find_mem_index(vma); | 656 | int mi = uio_find_mem_index(vma); |
657 | struct uio_mem *mem; | ||
657 | if (mi < 0) | 658 | if (mi < 0) |
658 | return -EINVAL; | 659 | return -EINVAL; |
660 | mem = idev->info->mem + mi; | ||
659 | 661 | ||
660 | vma->vm_ops = &uio_physical_vm_ops; | 662 | if (vma->vm_end - vma->vm_start > mem->size) |
663 | return -EINVAL; | ||
661 | 664 | ||
665 | vma->vm_ops = &uio_physical_vm_ops; | ||
662 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 666 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
663 | 667 | ||
668 | /* | ||
669 | * We cannot use the vm_iomap_memory() helper here, | ||
670 | * because vma->vm_pgoff is the map index we looked | ||
671 | * up above in uio_find_mem_index(), rather than an | ||
672 | * actual page offset into the mmap. | ||
673 | * | ||
674 | * So we just do the physical mmap without a page | ||
675 | * offset. | ||
676 | */ | ||
664 | return remap_pfn_range(vma, | 677 | return remap_pfn_range(vma, |
665 | vma->vm_start, | 678 | vma->vm_start, |
666 | idev->info->mem[mi].addr >> PAGE_SHIFT, | 679 | mem->addr >> PAGE_SHIFT, |
667 | vma->vm_end - vma->vm_start, | 680 | vma->vm_end - vma->vm_start, |
668 | vma->vm_page_prot); | 681 | vma->vm_page_prot); |
669 | } | 682 | } |
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c index ebeb9715f061..bdc515f5e979 100644 --- a/drivers/video/au1100fb.c +++ b/drivers/video/au1100fb.c | |||
@@ -361,37 +361,13 @@ void au1100fb_fb_rotate(struct fb_info *fbi, int angle) | |||
361 | int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma) | 361 | int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma) |
362 | { | 362 | { |
363 | struct au1100fb_device *fbdev; | 363 | struct au1100fb_device *fbdev; |
364 | unsigned int len; | ||
365 | unsigned long start=0, off; | ||
366 | 364 | ||
367 | fbdev = to_au1100fb_device(fbi); | 365 | fbdev = to_au1100fb_device(fbi); |
368 | 366 | ||
369 | if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) { | ||
370 | return -EINVAL; | ||
371 | } | ||
372 | |||
373 | start = fbdev->fb_phys & PAGE_MASK; | ||
374 | len = PAGE_ALIGN((start & ~PAGE_MASK) + fbdev->fb_len); | ||
375 | |||
376 | off = vma->vm_pgoff << PAGE_SHIFT; | ||
377 | |||
378 | if ((vma->vm_end - vma->vm_start + off) > len) { | ||
379 | return -EINVAL; | ||
380 | } | ||
381 | |||
382 | off += start; | ||
383 | vma->vm_pgoff = off >> PAGE_SHIFT; | ||
384 | |||
385 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 367 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
386 | pgprot_val(vma->vm_page_prot) |= (6 << 9); //CCA=6 | 368 | pgprot_val(vma->vm_page_prot) |= (6 << 9); //CCA=6 |
387 | 369 | ||
388 | if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, | 370 | return vm_iomap_memory(vma, fbdev->fb_phys, fbdev->fb_len); |
389 | vma->vm_end - vma->vm_start, | ||
390 | vma->vm_page_prot)) { | ||
391 | return -EAGAIN; | ||
392 | } | ||
393 | |||
394 | return 0; | ||
395 | } | 371 | } |
396 | 372 | ||
397 | static struct fb_ops au1100fb_ops = | 373 | static struct fb_ops au1100fb_ops = |
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c index 301224ecc950..1d02897d17f2 100644 --- a/drivers/video/au1200fb.c +++ b/drivers/video/au1200fb.c | |||
@@ -1233,34 +1233,13 @@ static int au1200fb_fb_blank(int blank_mode, struct fb_info *fbi) | |||
1233 | * method mainly to allow the use of the TLB streaming flag (CCA=6) | 1233 | * method mainly to allow the use of the TLB streaming flag (CCA=6) |
1234 | */ | 1234 | */ |
1235 | static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) | 1235 | static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) |
1236 | |||
1237 | { | 1236 | { |
1238 | unsigned int len; | ||
1239 | unsigned long start=0, off; | ||
1240 | struct au1200fb_device *fbdev = info->par; | 1237 | struct au1200fb_device *fbdev = info->par; |
1241 | 1238 | ||
1242 | if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) { | ||
1243 | return -EINVAL; | ||
1244 | } | ||
1245 | |||
1246 | start = fbdev->fb_phys & PAGE_MASK; | ||
1247 | len = PAGE_ALIGN((start & ~PAGE_MASK) + fbdev->fb_len); | ||
1248 | |||
1249 | off = vma->vm_pgoff << PAGE_SHIFT; | ||
1250 | |||
1251 | if ((vma->vm_end - vma->vm_start + off) > len) { | ||
1252 | return -EINVAL; | ||
1253 | } | ||
1254 | |||
1255 | off += start; | ||
1256 | vma->vm_pgoff = off >> PAGE_SHIFT; | ||
1257 | |||
1258 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 1239 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
1259 | pgprot_val(vma->vm_page_prot) |= _CACHE_MASK; /* CCA=7 */ | 1240 | pgprot_val(vma->vm_page_prot) |= _CACHE_MASK; /* CCA=7 */ |
1260 | 1241 | ||
1261 | return io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, | 1242 | return vm_iomap_memory(vma, fbdev->fb_phys, fbdev->fb_len); |
1262 | vma->vm_end - vma->vm_start, | ||
1263 | vma->vm_page_prot); | ||
1264 | } | 1243 | } |
1265 | 1244 | ||
1266 | static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) | 1245 | static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) |