]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.8-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 22 Apr 2013 17:46:48 +0000 (10:46 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 22 Apr 2013 17:46:48 +0000 (10:46 -0700)
added patches:
vm-add-vm_iomap_memory-helper-function.patch
vm-convert-fb_mmap-to-vm_iomap_memory-helper.patch
vm-convert-hpet-mmap-to-vm_iomap_memory-helper.patch
vm-convert-mtdchar-mmap-to-vm_iomap_memory-helper.patch
vm-convert-snd_pcm_lib_mmap_iomem-to-vm_iomap_memory-helper.patch

queue-3.8/series
queue-3.8/vm-add-vm_iomap_memory-helper-function.patch [new file with mode: 0644]
queue-3.8/vm-convert-fb_mmap-to-vm_iomap_memory-helper.patch [new file with mode: 0644]
queue-3.8/vm-convert-hpet-mmap-to-vm_iomap_memory-helper.patch [new file with mode: 0644]
queue-3.8/vm-convert-mtdchar-mmap-to-vm_iomap_memory-helper.patch [new file with mode: 0644]
queue-3.8/vm-convert-snd_pcm_lib_mmap_iomem-to-vm_iomap_memory-helper.patch [new file with mode: 0644]

index 0ad0df9c11ec1a4e2143a5887e83483f3889876b..14ec78a8947f2b57d844e1d9b54467bc404a7431 100644 (file)
@@ -32,3 +32,8 @@ perf-x86-fix-offcore_rsp-valid-mask-for-snb-ivb.patch
 userns-don-t-let-unprivileged-users-trick-privileged-users-into-setting-the-id_map.patch
 userns-check-uid_map-s-opener-s-fsuid-not-the-current-fsuid.patch
 userns-changing-any-namespace-id-mappings-should-require-privileges.patch
+vm-add-vm_iomap_memory-helper-function.patch
+vm-convert-snd_pcm_lib_mmap_iomem-to-vm_iomap_memory-helper.patch
+vm-convert-fb_mmap-to-vm_iomap_memory-helper.patch
+vm-convert-hpet-mmap-to-vm_iomap_memory-helper.patch
+vm-convert-mtdchar-mmap-to-vm_iomap_memory-helper.patch
diff --git a/queue-3.8/vm-add-vm_iomap_memory-helper-function.patch b/queue-3.8/vm-add-vm_iomap_memory-helper-function.patch
new file mode 100644 (file)
index 0000000..b9ebc47
--- /dev/null
@@ -0,0 +1,107 @@
+From b4cbb197c7e7a68dbad0d491242e3ca67420c13e Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Tue, 16 Apr 2013 13:45:37 -0700
+Subject: vm: add vm_iomap_memory() helper function
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+commit b4cbb197c7e7a68dbad0d491242e3ca67420c13e upstream.
+
+Various drivers end up replicating the code to mmap() their memory
+buffers into user space, and our core memory remapping function may be
+very flexible but it is unnecessarily complicated for the common cases
+to use.
+
+Our internal VM uses pfn's ("page frame numbers") which simplifies
+things for the VM, and allows us to pass physical addresses around in a
+denser and more efficient format than passing a "phys_addr_t" around,
+and having to shift it up and down by the page size.  But it just means
+that drivers end up doing that shifting instead at the interface level.
+
+It also means that drivers end up mucking around with internal VM things
+like the vma details (vm_pgoff, vm_start/end) way more than they really
+need to.
+
+So this just exports a function to map a certain physical memory range
+into user space (using a phys_addr_t based interface that is much more
+natural for a driver) and hides all the complexity from the driver.
+Some drivers will still end up tweaking the vm_page_prot details for
+things like prefetching or cacheability etc, but that's actually
+relevant to the driver, rather than caring about what the page offset of
+the mapping is into the particular IO memory region.
+
+Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+
+---
+ include/linux/mm.h |    2 ++
+ mm/memory.c        |   47 +++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 49 insertions(+)
+
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -1623,6 +1623,8 @@ int vm_insert_pfn(struct vm_area_struct
+                       unsigned long pfn);
+ int vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr,
+                       unsigned long pfn);
++int vm_iomap_memory(struct vm_area_struct *vma, phys_addr_t start, unsigned long len);
++
+ struct page *follow_page(struct vm_area_struct *, unsigned long address,
+                       unsigned int foll_flags);
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -2358,6 +2358,53 @@ int remap_pfn_range(struct vm_area_struc
+ }
+ EXPORT_SYMBOL(remap_pfn_range);
++/**
++ * vm_iomap_memory - remap memory to userspace
++ * @vma: user vma to map to
++ * @start: start of area
++ * @len: size of area
++ *
++ * This is a simplified io_remap_pfn_range() for common driver use. The
++ * driver just needs to give us the physical memory range to be mapped,
++ * we'll figure out the rest from the vma information.
++ *
++ * NOTE! Some drivers might want to tweak vma->vm_page_prot first to get
++ * whatever write-combining details or similar.
++ */
++int vm_iomap_memory(struct vm_area_struct *vma, phys_addr_t start, unsigned long len)
++{
++      unsigned long vm_len, pfn, pages;
++
++      /* Check that the physical memory area passed in looks valid */
++      if (start + len < start)
++              return -EINVAL;
++      /*
++       * You *really* shouldn't map things that aren't page-aligned,
++       * but we've historically allowed it because IO memory might
++       * just have smaller alignment.
++       */
++      len += start & ~PAGE_MASK;
++      pfn = start >> PAGE_SHIFT;
++      pages = (len + ~PAGE_MASK) >> PAGE_SHIFT;
++      if (pfn + pages < pfn)
++              return -EINVAL;
++
++      /* We start the mapping 'vm_pgoff' pages into the area */
++      if (vma->vm_pgoff > pages)
++              return -EINVAL;
++      pfn += vma->vm_pgoff;
++      pages -= vma->vm_pgoff;
++
++      /* Can we fit all of the mapping? */
++      vm_len = vma->vm_end - vma->vm_start;
++      if (vm_len >> PAGE_SHIFT > pages)
++              return -EINVAL;
++
++      /* Ok, let it rip */
++      return io_remap_pfn_range(vma, vma->vm_start, pfn, vm_len, vma->vm_page_prot);
++}
++EXPORT_SYMBOL(vm_iomap_memory);
++
+ static int apply_to_pte_range(struct mm_struct *mm, pmd_t *pmd,
+                                    unsigned long addr, unsigned long end,
+                                    pte_fn_t fn, void *data)
diff --git a/queue-3.8/vm-convert-fb_mmap-to-vm_iomap_memory-helper.patch b/queue-3.8/vm-convert-fb_mmap-to-vm_iomap_memory-helper.patch
new file mode 100644 (file)
index 0000000..d850505
--- /dev/null
@@ -0,0 +1,87 @@
+From fc9bbca8f650e5f738af8806317c0a041a48ae4a Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Fri, 19 Apr 2013 09:57:35 -0700
+Subject: vm: convert fb_mmap to vm_iomap_memory() helper
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+commit fc9bbca8f650e5f738af8806317c0a041a48ae4a upstream.
+
+This is my example conversion of a few existing mmap users.  The
+fb_mmap() case is a good example because it is a bit more complicated
+than some: fb_mmap() mmaps one of two different memory areas depending
+on the page offset of the mmap (but happily there is never any mixing of
+the two, so the helper function still works).
+
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/video/fbmem.c |   39 ++++++++++++++-------------------------
+ 1 file changed, 14 insertions(+), 25 deletions(-)
+
+--- a/drivers/video/fbmem.c
++++ b/drivers/video/fbmem.c
+@@ -1373,15 +1373,12 @@ fb_mmap(struct file *file, struct vm_are
+ {
+       struct fb_info *info = file_fb_info(file);
+       struct fb_ops *fb;
+-      unsigned long off;
++      unsigned long mmio_pgoff;
+       unsigned long start;
+       u32 len;
+       if (!info)
+               return -ENODEV;
+-      if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
+-              return -EINVAL;
+-      off = vma->vm_pgoff << PAGE_SHIFT;
+       fb = info->fbops;
+       if (!fb)
+               return -ENODEV;
+@@ -1393,32 +1390,24 @@ fb_mmap(struct file *file, struct vm_are
+               return res;
+       }
+-      /* frame buffer memory */
++      /*
++       * Ugh. This can be either the frame buffer mapping, or
++       * if pgoff points past it, the mmio mapping.
++       */
+       start = info->fix.smem_start;
+-      len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len);
+-      if (off >= len) {
+-              /* memory mapped io */
+-              off -= len;
+-              if (info->var.accel_flags) {
+-                      mutex_unlock(&info->mm_lock);
+-                      return -EINVAL;
+-              }
++      len = info->fix.smem_len;
++      mmio_pgoff = PAGE_ALIGN((start & ~PAGE_MASK) + len) >> PAGE_SHIFT;
++      if (vma->vm_pgoff >= mmio_pgoff) {
++              vma->vm_pgoff -= mmio_pgoff;
+               start = info->fix.mmio_start;
+-              len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len);
++              len = info->fix.mmio_len;
+       }
+       mutex_unlock(&info->mm_lock);
+-      start &= PAGE_MASK;
+-      if ((vma->vm_end - vma->vm_start + off) > len)
+-              return -EINVAL;
+-      off += start;
+-      vma->vm_pgoff = off >> PAGE_SHIFT;
+-      /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by io_remap_pfn_range()*/
++
+       vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+-      fb_pgprotect(file, vma, off);
+-      if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
+-                           vma->vm_end - vma->vm_start, vma->vm_page_prot))
+-              return -EAGAIN;
+-      return 0;
++      fb_pgprotect(file, vma, start);
++
++      return vm_iomap_memory(vma, start, len);
+ }
+ static int
diff --git a/queue-3.8/vm-convert-hpet-mmap-to-vm_iomap_memory-helper.patch b/queue-3.8/vm-convert-hpet-mmap-to-vm_iomap_memory-helper.patch
new file mode 100644 (file)
index 0000000..e02b9d9
--- /dev/null
@@ -0,0 +1,51 @@
+From 2323036dfec8ce3ce6e1c86a49a31b039f3300d1 Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Fri, 19 Apr 2013 09:46:39 -0700
+Subject: vm: convert HPET mmap to vm_iomap_memory() helper
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+commit 2323036dfec8ce3ce6e1c86a49a31b039f3300d1 upstream.
+
+This is my example conversion of a few existing mmap users.  The HPET
+case is simple, widely available, and easy to test (Clemens Ladisch sent
+a trivial test-program for it).
+
+Test-program-by: Clemens Ladisch <clemens@ladisch.de>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/hpet.c |   14 +-------------
+ 1 file changed, 1 insertion(+), 13 deletions(-)
+
+--- a/drivers/char/hpet.c
++++ b/drivers/char/hpet.c
+@@ -373,26 +373,14 @@ static int hpet_mmap(struct file *file,
+       struct hpet_dev *devp;
+       unsigned long addr;
+-      if (((vma->vm_end - vma->vm_start) != PAGE_SIZE) || vma->vm_pgoff)
+-              return -EINVAL;
+-
+       devp = file->private_data;
+       addr = devp->hd_hpets->hp_hpet_phys;
+       if (addr & (PAGE_SIZE - 1))
+               return -ENOSYS;
+-      vma->vm_flags |= VM_IO;
+       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+-
+-      if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT,
+-                                      PAGE_SIZE, vma->vm_page_prot)) {
+-              printk(KERN_ERR "%s: io_remap_pfn_range failed\n",
+-                      __func__);
+-              return -EAGAIN;
+-      }
+-
+-      return 0;
++      return vm_iomap_memory(vma, addr, PAGE_SIZE);
+ #else
+       return -ENOSYS;
+ #endif
diff --git a/queue-3.8/vm-convert-mtdchar-mmap-to-vm_iomap_memory-helper.patch b/queue-3.8/vm-convert-mtdchar-mmap-to-vm_iomap_memory-helper.patch
new file mode 100644 (file)
index 0000000..4127a43
--- /dev/null
@@ -0,0 +1,72 @@
+From 8558e4a26b00225efeb085725bc319f91201b239 Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Fri, 19 Apr 2013 09:53:07 -0700
+Subject: vm: convert mtdchar mmap to vm_iomap_memory() helper
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+commit 8558e4a26b00225efeb085725bc319f91201b239 upstream.
+
+This is my example conversion of a few existing mmap users.  The mtdchar
+case is actually disabled right now (and stays disabled), but I did it
+because it showed up on my "git grep", and I was familiar with the code
+due to fixing an overflow problem in the code in commit 9c603e53d380
+("mtdchar: fix offset overflow detection").
+
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/mtdchar.c |   32 ++------------------------------
+ 1 file changed, 2 insertions(+), 30 deletions(-)
+
+--- a/drivers/mtd/mtdchar.c
++++ b/drivers/mtd/mtdchar.c
+@@ -1159,45 +1159,17 @@ static int mtdchar_mmap(struct file *fil
+       struct mtd_file_info *mfi = file->private_data;
+       struct mtd_info *mtd = mfi->mtd;
+       struct map_info *map = mtd->priv;
+-      resource_size_t start, off;
+-      unsigned long len, vma_len;
+         /* This is broken because it assumes the MTD device is map-based
+          and that mtd->priv is a valid struct map_info.  It should be
+          replaced with something that uses the mtd_get_unmapped_area()
+          operation properly. */
+       if (0 /*mtd->type == MTD_RAM || mtd->type == MTD_ROM*/) {
+-              off = get_vm_offset(vma);
+-              start = map->phys;
+-              len = PAGE_ALIGN((start & ~PAGE_MASK) + map->size);
+-              start &= PAGE_MASK;
+-              vma_len = get_vm_size(vma);
+-
+-              /* Overflow in off+len? */
+-              if (vma_len + off < off)
+-                      return -EINVAL;
+-              /* Does it fit in the mapping? */
+-              if (vma_len + off > len)
+-                      return -EINVAL;
+-
+-              off += start;
+-              /* Did that overflow? */
+-              if (off < start)
+-                      return -EINVAL;
+-              if (set_vm_offset(vma, off) < 0)
+-                      return -EINVAL;
+-              vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
+-
+ #ifdef pgprot_noncached
+-              if (file->f_flags & O_DSYNC || off >= __pa(high_memory))
++              if (file->f_flags & O_DSYNC || map->phys >= __pa(high_memory))
+                       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ #endif
+-              if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
+-                                     vma->vm_end - vma->vm_start,
+-                                     vma->vm_page_prot))
+-                      return -EAGAIN;
+-
+-              return 0;
++              return vm_iomap_memory(vma, map->phys, map->size);
+       }
+       return -ENOSYS;
+ #else
diff --git a/queue-3.8/vm-convert-snd_pcm_lib_mmap_iomem-to-vm_iomap_memory-helper.patch b/queue-3.8/vm-convert-snd_pcm_lib_mmap_iomem-to-vm_iomap_memory-helper.patch
new file mode 100644 (file)
index 0000000..04d61c1
--- /dev/null
@@ -0,0 +1,43 @@
+From 0fe09a45c4848b5b5607b968d959fdc1821c161d Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Fri, 19 Apr 2013 10:01:04 -0700
+Subject: vm: convert snd_pcm_lib_mmap_iomem() to vm_iomap_memory() helper
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+commit 0fe09a45c4848b5b5607b968d959fdc1821c161d upstream.
+
+This is my example conversion of a few existing mmap users.  The pcm
+mmap case is one of the more straightforward ones.
+
+Acked-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/pcm_native.c |   12 ++----------
+ 1 file changed, 2 insertions(+), 10 deletions(-)
+
+--- a/sound/core/pcm_native.c
++++ b/sound/core/pcm_native.c
+@@ -3222,18 +3222,10 @@ EXPORT_SYMBOL_GPL(snd_pcm_lib_default_mm
+ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream,
+                          struct vm_area_struct *area)
+ {
+-      long size;
+-      unsigned long offset;
++      struct snd_pcm_runtime *runtime = substream->runtime;;
+       area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
+-      area->vm_flags |= VM_IO;
+-      size = area->vm_end - area->vm_start;
+-      offset = area->vm_pgoff << PAGE_SHIFT;
+-      if (io_remap_pfn_range(area, area->vm_start,
+-                              (substream->runtime->dma_addr + offset) >> PAGE_SHIFT,
+-                              size, area->vm_page_prot))
+-              return -EAGAIN;
+-      return 0;
++      return vm_iomap_memory(area, runtime->dma_addr, runtime->dma_bytes);
+ }
+ EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem);