From 797a60108a955bafbe0956052b1aa63d31f93754 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 22 Apr 2013 10:46:42 -0700 Subject: [PATCH] 3.4-stable patches 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.4/series | 5 + ...-add-vm_iomap_memory-helper-function.patch | 107 ++++++++++++++++++ ...rt-fb_mmap-to-vm_iomap_memory-helper.patch | 88 ++++++++++++++ ...-hpet-mmap-to-vm_iomap_memory-helper.patch | 51 +++++++++ ...dchar-mmap-to-vm_iomap_memory-helper.patch | 72 ++++++++++++ ...mmap_iomem-to-vm_iomap_memory-helper.patch | 43 +++++++ 6 files changed, 366 insertions(+) create mode 100644 queue-3.4/vm-add-vm_iomap_memory-helper-function.patch create mode 100644 queue-3.4/vm-convert-fb_mmap-to-vm_iomap_memory-helper.patch create mode 100644 queue-3.4/vm-convert-hpet-mmap-to-vm_iomap_memory-helper.patch create mode 100644 queue-3.4/vm-convert-mtdchar-mmap-to-vm_iomap_memory-helper.patch create mode 100644 queue-3.4/vm-convert-snd_pcm_lib_mmap_iomem-to-vm_iomap_memory-helper.patch diff --git a/queue-3.4/series b/queue-3.4/series index 729becb5317..23b77e1b765 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -18,3 +18,8 @@ crypto-algif-suppress-sending-source-address-information.patch perf-treat-attr.config-as-u64-in-perf_swevent_init.patch perf-x86-fix-offcore_rsp-valid-mask-for-snb-ivb.patch fbcon-fix-locking-harder.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.4/vm-add-vm_iomap_memory-helper-function.patch b/queue-3.4/vm-add-vm_iomap_memory-helper-function.patch new file mode 100644 index 00000000000..113b204be87 --- /dev/null +++ b/queue-3.4/vm-add-vm_iomap_memory-helper-function.patch @@ -0,0 +1,107 @@ +From b4cbb197c7e7a68dbad0d491242e3ca67420c13e Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Tue, 16 Apr 2013 13:45:37 -0700 +Subject: vm: add vm_iomap_memory() helper function + +From: Linus Torvalds + +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 +Signed-off-by: Linus Torvalds + +--- + include/linux/mm.h | 2 ++ + mm/memory.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 49 insertions(+) + +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -1507,6 +1507,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 +@@ -2329,6 +2329,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.4/vm-convert-fb_mmap-to-vm_iomap_memory-helper.patch b/queue-3.4/vm-convert-fb_mmap-to-vm_iomap_memory-helper.patch new file mode 100644 index 00000000000..191dc7d7e37 --- /dev/null +++ b/queue-3.4/vm-convert-fb_mmap-to-vm_iomap_memory-helper.patch @@ -0,0 +1,88 @@ +From fc9bbca8f650e5f738af8806317c0a041a48ae4a Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Fri, 19 Apr 2013 09:57:35 -0700 +Subject: vm: convert fb_mmap to vm_iomap_memory() helper + +From: Linus Torvalds + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/video/fbmem.c | 40 ++++++++++++++-------------------------- + 1 file changed, 14 insertions(+), 26 deletions(-) + +--- a/drivers/video/fbmem.c ++++ b/drivers/video/fbmem.c +@@ -1364,15 +1364,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; +@@ -1384,33 +1381,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; +- /* This is an IO map - tell maydump to skip this VMA */ +- vma->vm_flags |= VM_IO | VM_RESERVED; ++ + 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.4/vm-convert-hpet-mmap-to-vm_iomap_memory-helper.patch b/queue-3.4/vm-convert-hpet-mmap-to-vm_iomap_memory-helper.patch new file mode 100644 index 00000000000..e02b9d9af79 --- /dev/null +++ b/queue-3.4/vm-convert-hpet-mmap-to-vm_iomap_memory-helper.patch @@ -0,0 +1,51 @@ +From 2323036dfec8ce3ce6e1c86a49a31b039f3300d1 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Fri, 19 Apr 2013 09:46:39 -0700 +Subject: vm: convert HPET mmap to vm_iomap_memory() helper + +From: Linus Torvalds + +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 +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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.4/vm-convert-mtdchar-mmap-to-vm_iomap_memory-helper.patch b/queue-3.4/vm-convert-mtdchar-mmap-to-vm_iomap_memory-helper.patch new file mode 100644 index 00000000000..fbef7102fa7 --- /dev/null +++ b/queue-3.4/vm-convert-mtdchar-mmap-to-vm_iomap_memory-helper.patch @@ -0,0 +1,72 @@ +From 8558e4a26b00225efeb085725bc319f91201b239 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Fri, 19 Apr 2013 09:53:07 -0700 +Subject: vm: convert mtdchar mmap to vm_iomap_memory() helper + +From: Linus Torvalds + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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_RESERVED; +- + #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.4/vm-convert-snd_pcm_lib_mmap_iomem-to-vm_iomap_memory-helper.patch b/queue-3.4/vm-convert-snd_pcm_lib_mmap_iomem-to-vm_iomap_memory-helper.patch new file mode 100644 index 00000000000..fbb8e24bcd7 --- /dev/null +++ b/queue-3.4/vm-convert-snd_pcm_lib_mmap_iomem-to-vm_iomap_memory-helper.patch @@ -0,0 +1,43 @@ +From 0fe09a45c4848b5b5607b968d959fdc1821c161d Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +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 + +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 +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -3209,18 +3209,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); -- 2.47.3