Merge branch 'stable-3.2' into pandora-3.2
authorGrazvydas Ignotas <notasas@gmail.com>
Sun, 20 Aug 2017 14:34:06 +0000 (17:34 +0300)
committerGrazvydas Ignotas <notasas@gmail.com>
Sun, 20 Aug 2017 14:34:06 +0000 (17:34 +0300)
21 files changed:
1  2 
Documentation/kernel-parameters.txt
arch/arm/kernel/hw_breakpoint.c
arch/arm/kernel/ptrace.c
arch/arm/mm/dma-mapping.c
drivers/hid/hid-core.c
drivers/hid/hid-ids.h
drivers/mmc/card/block.c
drivers/mtd/ubi/upd.c
drivers/usb/gadget/inode.c
fs/exec.c
fs/proc/task_mmu.c
fs/splice.c
fs/ubifs/dir.c
fs/ubifs/tnc.c
fs/ubifs/xattr.c
include/linux/mm.h
kernel/sched.c
kernel/trace/trace.c
mm/huge_memory.c
mm/memory.c
mm/swapfile.c

@@@ -503,11 -503,6 +503,11 @@@ bytes respectively. Such letter suffixe
                        Also note the kernel might malfunction if you disable
                        some critical bits.
  
 +      cma=nn[MG]      [ARM,KNL]
 +                      Sets the size of kernel global memory area for contiguous
 +                      memory allocations. For more information, see
 +                      include/linux/dma-contiguous.h
 +
        cmo_free_hint=  [PPC] Format: { yes | no }
                        Specify whether pages are marked as being inactive
                        when they are freed.  This is used in CMO environments
                        a hypervisor.
                        Default: yes
  
 +      coherent_pool=nn[KMG]   [ARM,KNL]
 +                      Sets the size of memory pool for coherent, atomic dma
 +                      allocations, by default set to 256K.
 +
        code_bytes      [X86] How many bytes of object code to print
                        in an oops report.
                        Range: 0 - 8192
        no_debug_objects
                        [KNL] Disable object debugging
  
 +      debug_guardpage_minorder=
 +                      [KNL] When CONFIG_DEBUG_PAGEALLOC is set, this
 +                      parameter allows control of the order of pages that will
 +                      be intentionally kept free (and hence protected) by the
 +                      buddy allocator. Bigger value increase the probability
 +                      of catching random memory corruption, but reduce the
 +                      amount of memory for normal system use. The maximum
 +                      possible value is MAX_ORDER/2.  Setting this parameter
 +                      to 1 or 2 should be enough to identify most random
 +                      memory corruption problems caused by bugs in kernel or
 +                      driver code when a CPU writes to (or reads from) a
 +                      random memory location. Note that there exists a class
 +                      of memory corruptions problems caused by buggy H/W or
 +                      F/W or by drivers badly programing DMA (basically when
 +                      memory is written at bus level and the CPU MMU is
 +                      bypassed) which are not detectable by
 +                      CONFIG_DEBUG_PAGEALLOC, hence this option will not help
 +                      tracking down these problems.
 +
        debugpat        [X86] Enable PAT debugging
  
        decnet.addr=    [HW,NET]
        spia_pedr=
        spia_peddr=
  
+       stack_guard_gap=        [MM]
+                       override the default stack gap protection. The value
+                       is in page units and it defines how many pages prior
+                       to (for stacks growing down) resp. after (for stacks
+                       growing up) the main stack are reserved for no other
+                       mapping. Default value is 256 pages.
        stacktrace      [FTRACE]
                        Enabled the stack tracer on boot up.
  
@@@ -1001,6 -1001,22 +1001,22 @@@ static int __init arch_hw_breakpoint_in
                return 0;
        }
  
+       /*
+        * Scorpion CPUs (at least those in APQ8060) seem to set DBGPRSR.SPD
+        * whenever a WFI is issued, even if the core is not powered down, in
+        * violation of the architecture.  When DBGPRSR.SPD is set, accesses to
+        * breakpoint and watchpoint registers are treated as undefined, so
+        * this results in boot time and runtime failures when these are
+        * accessed and we unexpectedly take a trap.
+        *
+        * It's not clear if/how this can be worked around, so we blacklist
+        * Scorpion CPUs to avoid these issues.
+       */
+       if ((read_cpuid_id() & 0xff00fff0) == ARM_CPU_PART_SCORPION) {
+               pr_info("Scorpion CPU detected. Hardware breakpoints and watchpoints disabled\n");
+               return 0;
+       }
        /* Determine how many BRPs/WRPs are available. */
        core_num_brps = get_num_brps();
        core_num_wrps = get_num_wrps();
        }
  
        /* Register debug fault handler. */
 -      hook_fault_code(2, hw_breakpoint_pending, SIGTRAP, TRAP_HWBKPT,
 -                      "watchpoint debug exception");
 -      hook_ifault_code(2, hw_breakpoint_pending, SIGTRAP, TRAP_HWBKPT,
 -                      "breakpoint debug exception");
 +      hook_fault_code(FAULT_CODE_DEBUG, hw_breakpoint_pending, SIGTRAP,
 +                      TRAP_HWBKPT, "watchpoint debug exception");
 +      hook_ifault_code(FAULT_CODE_DEBUG, hw_breakpoint_pending, SIGTRAP,
 +                      TRAP_HWBKPT, "breakpoint debug exception");
  
        /* Register hotplug notifier. */
        register_cpu_notifier(&dbg_reset_nb);
diff --combined arch/arm/kernel/ptrace.c
@@@ -593,7 -593,7 +593,7 @@@ static int gpr_set(struct task_struct *
                   const void *kbuf, const void __user *ubuf)
  {
        int ret;
-       struct pt_regs newregs;
+       struct pt_regs newregs = *task_pt_regs(target);
  
        ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
                                 &newregs,
@@@ -842,7 -842,7 +842,7 @@@ long arch_ptrace(struct task_struct *ch
  #endif
  
                case PTRACE_GET_THREAD_AREA:
 -                      ret = put_user(task_thread_info(child)->tp_value,
 +                      ret = put_user(task_thread_info(child)->tp_value[0],
                                       datap);
                        break;
  
  #include <linux/init.h>
  #include <linux/device.h>
  #include <linux/dma-mapping.h>
 +#include <linux/dma-contiguous.h>
  #include <linux/highmem.h>
 +#include <linux/memblock.h>
  #include <linux/slab.h>
 +#include <linux/iommu.h>
 +#include <linux/io.h>
 +#include <linux/vmalloc.h>
  
  #include <asm/memory.h>
  #include <asm/highmem.h>
  #include <asm/tlbflush.h>
  #include <asm/sizes.h>
  #include <asm/mach/arch.h>
 +#include <asm/dma-iommu.h>
 +#include <asm/mach/map.h>
 +#include <asm/system.h>
 +#include <asm/dma-contiguous.h>
  
  #include "mm.h"
  
 +/*
 + * The DMA API is built upon the notion of "buffer ownership".  A buffer
 + * is either exclusively owned by the CPU (and therefore may be accessed
 + * by it) or exclusively owned by the DMA device.  These helper functions
 + * represent the transitions between these two ownership states.
 + *
 + * Note, however, that on later ARMs, this notion does not work due to
 + * speculative prefetches.  We model our approach on the assumption that
 + * the CPU does do speculative prefetches, which means we clean caches
 + * before transfers and delay cache invalidation until transfer completion.
 + *
 + */
 +static void __dma_page_cpu_to_dev(struct page *, unsigned long,
 +              size_t, enum dma_data_direction);
 +static void __dma_page_dev_to_cpu(struct page *, unsigned long,
 +              size_t, enum dma_data_direction);
 +
 +/**
 + * arm_dma_map_page - map a portion of a page for streaming DMA
 + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
 + * @page: page that buffer resides in
 + * @offset: offset into page for start of buffer
 + * @size: size of buffer to map
 + * @dir: DMA transfer direction
 + *
 + * Ensure that any data held in the cache is appropriately discarded
 + * or written back.
 + *
 + * The device owns this memory once this call has completed.  The CPU
 + * can regain ownership by calling dma_unmap_page().
 + */
 +static dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
 +           unsigned long offset, size_t size, enum dma_data_direction dir,
 +           struct dma_attrs *attrs)
 +{
 +      if (!arch_is_coherent())
 +              __dma_page_cpu_to_dev(page, offset, size, dir);
 +      return pfn_to_dma(dev, page_to_pfn(page)) + offset;
 +}
 +
 +/**
 + * arm_dma_unmap_page - unmap a buffer previously mapped through dma_map_page()
 + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
 + * @handle: DMA address of buffer
 + * @size: size of buffer (same as passed to dma_map_page)
 + * @dir: DMA transfer direction (same as passed to dma_map_page)
 + *
 + * Unmap a page streaming mode DMA translation.  The handle and size
 + * must match what was provided in the previous dma_map_page() call.
 + * All other usages are undefined.
 + *
 + * After this call, reads by the CPU to the buffer are guaranteed to see
 + * whatever the device wrote there.
 + */
 +static void arm_dma_unmap_page(struct device *dev, dma_addr_t handle,
 +              size_t size, enum dma_data_direction dir,
 +              struct dma_attrs *attrs)
 +{
 +      if (!arch_is_coherent())
 +              __dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)),
 +                                    handle & ~PAGE_MASK, size, dir);
 +}
 +
 +static void arm_dma_sync_single_for_cpu(struct device *dev,
 +              dma_addr_t handle, size_t size, enum dma_data_direction dir)
 +{
 +      unsigned int offset = handle & (PAGE_SIZE - 1);
 +      struct page *page = pfn_to_page(dma_to_pfn(dev, handle-offset));
 +      if (!arch_is_coherent())
 +              __dma_page_dev_to_cpu(page, offset, size, dir);
 +}
 +
 +static void arm_dma_sync_single_for_device(struct device *dev,
 +              dma_addr_t handle, size_t size, enum dma_data_direction dir)
 +{
 +      unsigned int offset = handle & (PAGE_SIZE - 1);
 +      struct page *page = pfn_to_page(dma_to_pfn(dev, handle-offset));
 +      if (!arch_is_coherent())
 +              __dma_page_cpu_to_dev(page, offset, size, dir);
 +}
 +
 +static int arm_dma_set_mask(struct device *dev, u64 dma_mask);
 +
 +struct dma_map_ops arm_dma_ops = {
 +      .alloc                  = arm_dma_alloc,
 +      .free                   = arm_dma_free,
 +      .mmap                   = arm_dma_mmap,
 +      .map_page               = arm_dma_map_page,
 +      .unmap_page             = arm_dma_unmap_page,
 +      .map_sg                 = arm_dma_map_sg,
 +      .unmap_sg               = arm_dma_unmap_sg,
 +      .sync_single_for_cpu    = arm_dma_sync_single_for_cpu,
 +      .sync_single_for_device = arm_dma_sync_single_for_device,
 +      .sync_sg_for_cpu        = arm_dma_sync_sg_for_cpu,
 +      .sync_sg_for_device     = arm_dma_sync_sg_for_device,
 +      .set_dma_mask           = arm_dma_set_mask,
 +};
 +EXPORT_SYMBOL(arm_dma_ops);
 +
  static u64 get_coherent_dma_mask(struct device *dev)
  {
        u64 mask = (u64)arm_dma_limit;
        return mask;
  }
  
 +static void __dma_clear_buffer(struct page *page, size_t size)
 +{
 +      void *ptr;
 +      /*
 +       * Ensure that the allocated pages are zeroed, and that any data
 +       * lurking in the kernel direct-mapped region is invalidated.
 +       */
 +      ptr = page_address(page);
 +      if (ptr) {
 +              memset(ptr, 0, size);
 +              dmac_flush_range(ptr, ptr + size);
 +              outer_flush_range(__pa(ptr), __pa(ptr) + size);
 +      }
 +}
 +
  /*
   * Allocate a DMA buffer for 'dev' of size 'size' using the
   * specified gfp mask.  Note that 'size' must be page aligned.
@@@ -187,6 -64,23 +187,6 @@@ static struct page *__dma_alloc_buffer(
  {
        unsigned long order = get_order(size);
        struct page *page, *p, *e;
 -      void *ptr;
 -      u64 mask = get_coherent_dma_mask(dev);
 -
 -#ifdef CONFIG_DMA_API_DEBUG
 -      u64 limit = (mask + 1) & ~mask;
 -      if (limit && size >= limit) {
 -              dev_warn(dev, "coherent allocation too big (requested %#x mask %#llx)\n",
 -                      size, mask);
 -              return NULL;
 -      }
 -#endif
 -
 -      if (!mask)
 -              return NULL;
 -
 -      if (mask < 0xffffffffULL)
 -              gfp |= GFP_DMA;
  
        page = alloc_pages(gfp, order);
        if (!page)
        for (p = page + (size >> PAGE_SHIFT), e = page + (1 << order); p < e; p++)
                __free_page(p);
  
 -      /*
 -       * Ensure that the allocated pages are zeroed, and that any data
 -       * lurking in the kernel direct-mapped region is invalidated.
 -       */
 -      ptr = page_address(page);
 -      memset(ptr, 0, size);
 -      dmac_flush_range(ptr, ptr + size);
 -      outer_flush_range(__pa(ptr), __pa(ptr) + size);
 +      __dma_clear_buffer(page, size);
  
        return page;
  }
@@@ -219,346 -120,218 +219,346 @@@ static void __dma_free_buffer(struct pa
  
  #ifdef CONFIG_MMU
  
 -#define CONSISTENT_OFFSET(x)  (((unsigned long)(x) - consistent_base) >> PAGE_SHIFT)
 -#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - consistent_base) >> PMD_SHIFT)
 -
 -/*
 - * These are the page tables (2MB each) covering uncached, DMA consistent allocations
 - */
 -static pte_t **consistent_pte;
 -
 -#define DEFAULT_CONSISTENT_DMA_SIZE SZ_2M
 +static void *__alloc_from_contiguous(struct device *dev, size_t size,
 +                                   pgprot_t prot, struct page **ret_page);
  
 -unsigned long consistent_base = CONSISTENT_END - DEFAULT_CONSISTENT_DMA_SIZE;
 +static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp,
 +                               pgprot_t prot, struct page **ret_page,
 +                               const void *caller);
  
 -void __init init_consistent_dma_size(unsigned long size)
 +static void *
 +__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot,
 +      const void *caller)
  {
 -      unsigned long base = CONSISTENT_END - ALIGN(size, SZ_2M);
 +      struct vm_struct *area;
 +      unsigned long addr;
  
 -      BUG_ON(consistent_pte); /* Check we're called before DMA region init */
 -      BUG_ON(base < VMALLOC_END);
 +      /*
 +       * DMA allocation can be mapped to user space, so lets
 +       * set VM_USERMAP flags too.
 +       */
 +      area = get_vm_area_caller(size, VM_ARM_DMA_CONSISTENT | VM_USERMAP,
 +                                caller);
 +      if (!area)
 +              return NULL;
 +      addr = (unsigned long)area->addr;
 +      area->phys_addr = __pfn_to_phys(page_to_pfn(page));
 +
 +      if (ioremap_page_range(addr, addr + size, area->phys_addr, prot)) {
 +              vunmap((void *)addr);
 +              return NULL;
 +      }
 +      return (void *)addr;
 +}
  
 -      /* Grow region to accommodate specified size  */
 -      if (base < consistent_base)
 -              consistent_base = base;
 +static void __dma_free_remap(void *cpu_addr, size_t size)
 +{
 +      unsigned int flags = VM_ARM_DMA_CONSISTENT | VM_USERMAP;
 +      struct vm_struct *area = find_vm_area(cpu_addr);
 +      if (!area || (area->flags & flags) != flags) {
 +              WARN(1, "trying to free invalid coherent area: %p\n", cpu_addr);
 +              return;
 +      }
 +      unmap_kernel_range((unsigned long)cpu_addr, size);
 +      vunmap(cpu_addr);
  }
  
 -#include "vmregion.h"
 +struct dma_pool {
 +      size_t size;
 +      spinlock_t lock;
 +      unsigned long *bitmap;
 +      unsigned long nr_pages;
 +      void *vaddr;
 +      struct page *page;
 +};
  
 -static struct arm_vmregion_head consistent_head = {
 -      .vm_lock        = __SPIN_LOCK_UNLOCKED(&consistent_head.vm_lock),
 -      .vm_list        = LIST_HEAD_INIT(consistent_head.vm_list),
 -      .vm_end         = CONSISTENT_END,
 +static struct dma_pool atomic_pool = {
 +      .size = SZ_256K,
  };
  
 -#ifdef CONFIG_HUGETLB_PAGE
 -#error ARM Coherent DMA allocator does not (yet) support huge TLB
 -#endif
 +static int __init early_coherent_pool(char *p)
 +{
 +      atomic_pool.size = memparse(p, &p);
 +      return 0;
 +}
 +early_param("coherent_pool", early_coherent_pool);
  
  /*
 - * Initialise the consistent memory allocation.
 + * Initialise the coherent pool for atomic allocations.
   */
 -static int __init consistent_init(void)
 +static int __init atomic_pool_init(void)
  {
 -      int ret = 0;
 -      pgd_t *pgd;
 -      pud_t *pud;
 -      pmd_t *pmd;
 -      pte_t *pte;
 -      int i = 0;
 -      unsigned long base = consistent_base;
 -      unsigned long num_ptes = (CONSISTENT_END - base) >> PMD_SHIFT;
 +      struct dma_pool *pool = &atomic_pool;
 +      pgprot_t prot = pgprot_dmacoherent(pgprot_kernel);
 +      unsigned long nr_pages = pool->size >> PAGE_SHIFT;
 +      unsigned long *bitmap;
 +      struct page *page;
 +      void *ptr;
 +      int bitmap_size = BITS_TO_LONGS(nr_pages) * sizeof(long);
  
 -      consistent_pte = kmalloc(num_ptes * sizeof(pte_t), GFP_KERNEL);
 -      if (!consistent_pte) {
 -              pr_err("%s: no memory\n", __func__);
 -              return -ENOMEM;
 +      bitmap = kzalloc(bitmap_size, GFP_KERNEL);
 +      if (!bitmap)
 +              goto no_bitmap;
 +
 +      if (IS_ENABLED(CONFIG_CMA))
 +              ptr = __alloc_from_contiguous(NULL, pool->size, prot, &page);
 +      else
 +              ptr = __alloc_remap_buffer(NULL, pool->size, GFP_KERNEL, prot,
 +                                         &page, NULL);
 +      if (ptr) {
 +              spin_lock_init(&pool->lock);
 +              pool->vaddr = ptr;
 +              pool->page = page;
 +              pool->bitmap = bitmap;
 +              pool->nr_pages = nr_pages;
 +              pr_info("DMA: preallocated %u KiB pool for atomic coherent allocations\n",
 +                     (unsigned)pool->size / 1024);
 +              return 0;
        }
 +      kfree(bitmap);
 +no_bitmap:
 +      pr_err("DMA: failed to allocate %u KiB pool for atomic coherent allocation\n",
 +             (unsigned)pool->size / 1024);
 +      return -ENOMEM;
 +}
 +/*
 + * CMA is activated by core_initcall, so we must be called after it.
 + */
 +postcore_initcall(atomic_pool_init);
  
 -      pr_debug("DMA memory: 0x%08lx - 0x%08lx:\n", base, CONSISTENT_END);
 -      consistent_head.vm_start = base;
 +struct dma_contig_early_reserve {
 +      phys_addr_t base;
 +      unsigned long size;
 +};
  
 -      do {
 -              pgd = pgd_offset(&init_mm, base);
 +static struct dma_contig_early_reserve dma_mmu_remap[MAX_CMA_AREAS] __initdata;
  
 -              pud = pud_alloc(&init_mm, pgd, base);
 -              if (!pud) {
 -                      printk(KERN_ERR "%s: no pud tables\n", __func__);
 -                      ret = -ENOMEM;
 -                      break;
 -              }
 +static int dma_mmu_remap_num __initdata;
  
 -              pmd = pmd_alloc(&init_mm, pud, base);
 -              if (!pmd) {
 -                      printk(KERN_ERR "%s: no pmd tables\n", __func__);
 -                      ret = -ENOMEM;
 -                      break;
 -              }
 -              WARN_ON(!pmd_none(*pmd));
 +void __init dma_contiguous_early_fixup(phys_addr_t base, unsigned long size)
 +{
 +      dma_mmu_remap[dma_mmu_remap_num].base = base;
 +      dma_mmu_remap[dma_mmu_remap_num].size = size;
 +      dma_mmu_remap_num++;
 +}
  
 -              pte = pte_alloc_kernel(pmd, base);
 -              if (!pte) {
 -                      printk(KERN_ERR "%s: no pte tables\n", __func__);
 -                      ret = -ENOMEM;
 -                      break;
 -              }
 +void __init dma_contiguous_remap(void)
 +{
 +      int i;
 +      for (i = 0; i < dma_mmu_remap_num; i++) {
 +              phys_addr_t start = dma_mmu_remap[i].base;
 +              phys_addr_t end = start + dma_mmu_remap[i].size;
 +              struct map_desc map;
 +              unsigned long addr;
 +
 +              if (end > arm_lowmem_limit)
 +                      end = arm_lowmem_limit;
 +              if (start >= end)
 +                      return;
 +
 +              map.pfn = __phys_to_pfn(start);
 +              map.virtual = __phys_to_virt(start);
 +              map.length = end - start;
 +              map.type = MT_MEMORY_DMA_READY;
  
 -              consistent_pte[i++] = pte;
 -              base += PMD_SIZE;
 -      } while (base < CONSISTENT_END);
 +              /*
 +               * Clear previous low-memory mapping
 +               */
 +              for (addr = __phys_to_virt(start); addr < __phys_to_virt(end);
 +                   addr += PMD_SIZE)
 +                      pmd_clear(pmd_off_k(addr));
  
 -      return ret;
 +              iotable_init(&map, 1);
 +      }
  }
  
 -core_initcall(consistent_init);
 +static int __dma_update_pte(pte_t *pte, pgtable_t token, unsigned long addr,
 +                          void *data)
 +{
 +      struct page *page = virt_to_page(addr);
 +      pgprot_t prot = *(pgprot_t *)data;
  
 -static void *
 -__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot)
 +      set_pte_ext(pte, mk_pte(page, prot), 0);
 +      return 0;
 +}
 +
 +static void __dma_remap(struct page *page, size_t size, pgprot_t prot)
 +{
 +      unsigned long start = (unsigned long) page_address(page);
 +      unsigned end = start + size;
 +
 +      apply_to_page_range(&init_mm, start, size, __dma_update_pte, &prot);
 +      dsb();
 +      flush_tlb_kernel_range(start, end);
 +}
 +
 +static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp,
 +                               pgprot_t prot, struct page **ret_page,
 +                               const void *caller)
  {
 -      struct arm_vmregion *c;
 -      size_t align;
 -      int bit;
 +      struct page *page;
 +      void *ptr;
 +      page = __dma_alloc_buffer(dev, size, gfp);
 +      if (!page)
 +              return NULL;
 +
 +      ptr = __dma_alloc_remap(page, size, gfp, prot, caller);
 +      if (!ptr) {
 +              __dma_free_buffer(page, size);
 +              return NULL;
 +      }
 +
 +      *ret_page = page;
 +      return ptr;
 +}
  
 -      if (!consistent_pte) {
 -              printk(KERN_ERR "%s: not initialised\n", __func__);
 -              dump_stack();
 +static void *__alloc_from_pool(size_t size, struct page **ret_page)
 +{
 +      struct dma_pool *pool = &atomic_pool;
 +      unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
 +      unsigned int pageno;
 +      unsigned long flags;
 +      void *ptr = NULL;
 +      unsigned long align_mask;
 +
 +      if (!pool->vaddr) {
 +              WARN(1, "coherent pool not initialised!\n");
                return NULL;
        }
  
        /*
 -       * Align the virtual region allocation - maximum alignment is
 -       * a section size, minimum is a page size.  This helps reduce
 -       * fragmentation of the DMA space, and also prevents allocations
 -       * smaller than a section from crossing a section boundary.
 +       * Align the region allocation - allocations from pool are rather
 +       * small, so align them to their order in pages, minimum is a page
 +       * size. This helps reduce fragmentation of the DMA space.
         */
 -      bit = fls(size - 1);
 -      if (bit > SECTION_SHIFT)
 -              bit = SECTION_SHIFT;
 -      align = 1 << bit;
 +      align_mask = (1 << get_order(size)) - 1;
 +
 +      spin_lock_irqsave(&pool->lock, flags);
 +      pageno = bitmap_find_next_zero_area(pool->bitmap, pool->nr_pages,
 +                                          0, count, align_mask);
 +      if (pageno < pool->nr_pages) {
 +              bitmap_set(pool->bitmap, pageno, count);
 +              ptr = pool->vaddr + PAGE_SIZE * pageno;
 +              *ret_page = pool->page + pageno;
 +      } else {
 +              pr_err_once("ERROR: %u KiB atomic DMA coherent pool is too small!\n"
 +                          "Please increase it with coherent_pool= kernel parameter!\n",
 +                          (unsigned)pool->size / 1024);
 +      }
 +      spin_unlock_irqrestore(&pool->lock, flags);
  
 -      /*
 -       * Allocate a virtual address in the consistent mapping region.
 -       */
 -      c = arm_vmregion_alloc(&consistent_head, align, size,
 -                          gfp & ~(__GFP_DMA | __GFP_HIGHMEM));
 -      if (c) {
 -              pte_t *pte;
 -              int idx = CONSISTENT_PTE_INDEX(c->vm_start);
 -              u32 off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
 -
 -              pte = consistent_pte[idx] + off;
 -              c->vm_pages = page;
 -
 -              do {
 -                      BUG_ON(!pte_none(*pte));
 -
 -                      set_pte_ext(pte, mk_pte(page, prot), 0);
 -                      page++;
 -                      pte++;
 -                      off++;
 -                      if (off >= PTRS_PER_PTE) {
 -                              off = 0;
 -                              pte = consistent_pte[++idx];
 -                      }
 -              } while (size -= PAGE_SIZE);
 +      return ptr;
 +}
  
 -              dsb();
 +static int __free_from_pool(void *start, size_t size)
 +{
 +      struct dma_pool *pool = &atomic_pool;
 +      unsigned long pageno, count;
 +      unsigned long flags;
 +
 +      if (start < pool->vaddr || start > pool->vaddr + pool->size)
 +              return 0;
  
 -              return (void *)c->vm_start;
 +      if (start + size > pool->vaddr + pool->size) {
 +              WARN(1, "freeing wrong coherent size from pool\n");
 +              return 0;
        }
 -      return NULL;
 +
 +      pageno = (start - pool->vaddr) >> PAGE_SHIFT;
 +      count = size >> PAGE_SHIFT;
 +
 +      spin_lock_irqsave(&pool->lock, flags);
 +      bitmap_clear(pool->bitmap, pageno, count);
 +      spin_unlock_irqrestore(&pool->lock, flags);
 +
 +      return 1;
  }
  
 -static void __dma_free_remap(void *cpu_addr, size_t size)
 +static void *__alloc_from_contiguous(struct device *dev, size_t size,
 +                                   pgprot_t prot, struct page **ret_page)
  {
 -      struct arm_vmregion *c;
 -      unsigned long addr;
 -      pte_t *ptep;
 -      int idx;
 -      u32 off;
 -
 -      c = arm_vmregion_find_remove(&consistent_head, (unsigned long)cpu_addr);
 -      if (!c) {
 -              printk(KERN_ERR "%s: trying to free invalid coherent area: %p\n",
 -                     __func__, cpu_addr);
 -              dump_stack();
 -              return;
 -      }
 +      unsigned long order = get_order(size);
 +      size_t count = size >> PAGE_SHIFT;
 +      struct page *page;
  
 -      if ((c->vm_end - c->vm_start) != size) {
 -              printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n",
 -                     __func__, c->vm_end - c->vm_start, size);
 -              dump_stack();
 -              size = c->vm_end - c->vm_start;
 -      }
 +      page = dma_alloc_from_contiguous(dev, count, order);
 +      if (!page)
 +              return NULL;
  
 -      idx = CONSISTENT_PTE_INDEX(c->vm_start);
 -      off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
 -      ptep = consistent_pte[idx] + off;
 -      addr = c->vm_start;
 -      do {
 -              pte_t pte = ptep_get_and_clear(&init_mm, addr, ptep);
 -
 -              ptep++;
 -              addr += PAGE_SIZE;
 -              off++;
 -              if (off >= PTRS_PER_PTE) {
 -                      off = 0;
 -                      ptep = consistent_pte[++idx];
 -              }
 +      __dma_clear_buffer(page, size);
 +      __dma_remap(page, size, prot);
  
 -              if (pte_none(pte) || !pte_present(pte))
 -                      printk(KERN_CRIT "%s: bad page in kernel page table\n",
 -                             __func__);
 -      } while (size -= PAGE_SIZE);
 +      *ret_page = page;
 +      return page_address(page);
 +}
  
 -      flush_tlb_kernel_range(c->vm_start, c->vm_end);
 +static void __free_from_contiguous(struct device *dev, struct page *page,
 +                                 size_t size)
 +{
 +      __dma_remap(page, size, pgprot_kernel);
 +      dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
 +}
  
 -      arm_vmregion_free(&consistent_head, c);
 +static inline pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot)
 +{
 +      prot = dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs) ?
 +                          pgprot_writecombine(prot) :
 +                          pgprot_dmacoherent(prot);
 +      return prot;
  }
  
 +#define nommu() 0
 +
  #else /* !CONFIG_MMU */
  
 -#define __dma_alloc_remap(page, size, gfp, prot)      page_address(page)
 -#define __dma_free_remap(addr, size)                  do { } while (0)
 +#define nommu() 1
 +
 +#define __get_dma_pgprot(attrs, prot) __pgprot(0)
 +#define __alloc_remap_buffer(dev, size, gfp, prot, ret, c)    NULL
 +#define __alloc_from_pool(size, ret_page)                     NULL
 +#define __alloc_from_contiguous(dev, size, prot, ret)         NULL
 +#define __free_from_pool(cpu_addr, size)                      0
 +#define __free_from_contiguous(dev, page, size)                       do { } while (0)
 +#define __dma_free_remap(cpu_addr, size)                      do { } while (0)
  
  #endif        /* CONFIG_MMU */
  
 -static void *
 -__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
 -          pgprot_t prot)
 +static void *__alloc_simple_buffer(struct device *dev, size_t size, gfp_t gfp,
 +                                 struct page **ret_page)
 +{
 +      struct page *page;
 +      page = __dma_alloc_buffer(dev, size, gfp);
 +      if (!page)
 +              return NULL;
 +
 +      *ret_page = page;
 +      return page_address(page);
 +}
 +
 +
 +
 +static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
 +                       gfp_t gfp, pgprot_t prot, const void *caller)
  {
 +      u64 mask = get_coherent_dma_mask(dev);
        struct page *page;
        void *addr;
  
 +#ifdef CONFIG_DMA_API_DEBUG
 +      u64 limit = (mask + 1) & ~mask;
 +      if (limit && size >= limit) {
 +              dev_warn(dev, "coherent allocation too big (requested %#x mask %#llx)\n",
 +                      size, mask);
 +              return NULL;
 +      }
 +#endif
 +
 +      if (!mask)
 +              return NULL;
 +
 +      if (mask < 0xffffffffULL)
 +              gfp |= GFP_DMA;
 +
        /*
         * Following is a work-around (a.k.a. hack) to prevent pages
         * with __GFP_COMP being passed to split_page() which cannot
         */
        gfp &= ~(__GFP_COMP);
  
 -      *handle = ~0;
 +      *handle = DMA_ERROR_CODE;
        size = PAGE_ALIGN(size);
  
 -      page = __dma_alloc_buffer(dev, size, gfp);
 -      if (!page)
 -              return NULL;
 -
 -      if (!arch_is_coherent())
 -              addr = __dma_alloc_remap(page, size, gfp, prot);
 +      if (arch_is_coherent() || nommu())
 +              addr = __alloc_simple_buffer(dev, size, gfp, &page);
 +      else if (gfp & GFP_ATOMIC)
 +              addr = __alloc_from_pool(size, &page);
 +      else if (!IS_ENABLED(CONFIG_CMA))
 +              addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, caller);
        else
 -              addr = page_address(page);
 +              addr = __alloc_from_contiguous(dev, size, prot, &page);
  
        if (addr)
                *handle = pfn_to_dma(dev, page_to_pfn(page));
 -      else
 -              __dma_free_buffer(page, size);
  
        return addr;
  }
   * Allocate DMA-coherent memory space and return both the kernel remapped
   * virtual and bus address for that space.
   */
 -void *
 -dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
 +void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
 +                  gfp_t gfp, struct dma_attrs *attrs)
  {
-       pgprot_t prot = __get_dma_pgprot(attrs, pgprot_kernel);
++      pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
        void *memory;
  
        if (dma_alloc_from_coherent(dev, size, handle, &memory))
                return memory;
  
 -      return __dma_alloc(dev, size, handle, gfp,
 -                         pgprot_dmacoherent(PAGE_KERNEL));
 +      return __dma_alloc(dev, size, handle, gfp, prot,
 +                         __builtin_return_address(0));
  }
 -EXPORT_SYMBOL(dma_alloc_coherent);
  
  /*
 - * Allocate a writecombining region, in much the same way as
 - * dma_alloc_coherent above.
 + * Create userspace mapping for the DMA-coherent memory.
   */
 -void *
 -dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
 -{
 -      return __dma_alloc(dev, size, handle, gfp,
 -                         pgprot_writecombine(PAGE_KERNEL));
 -}
 -EXPORT_SYMBOL(dma_alloc_writecombine);
 -
 -static int dma_mmap(struct device *dev, struct vm_area_struct *vma,
 -                  void *cpu_addr, dma_addr_t dma_addr, size_t size)
 +int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
 +               void *cpu_addr, dma_addr_t dma_addr, size_t size,
 +               struct dma_attrs *attrs)
  {
        int ret = -ENXIO;
  #ifdef CONFIG_MMU
 -      unsigned long user_size, kern_size;
 -      struct arm_vmregion *c;
 -
 -      user_size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
 +      unsigned long nr_vma_pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
 +      unsigned long nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
 +      unsigned long pfn = dma_to_pfn(dev, dma_addr);
 +      unsigned long off = vma->vm_pgoff;
  
 -      c = arm_vmregion_find(&consistent_head, (unsigned long)cpu_addr);
 -      if (c) {
 -              unsigned long off = vma->vm_pgoff;
 +      vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
  
 -              kern_size = (c->vm_end - c->vm_start) >> PAGE_SHIFT;
 +      if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret))
 +              return ret;
  
 -              if (off < kern_size &&
 -                  user_size <= (kern_size - off)) {
 -                      ret = remap_pfn_range(vma, vma->vm_start,
 -                                            page_to_pfn(c->vm_pages) + off,
 -                                            user_size << PAGE_SHIFT,
 -                                            vma->vm_page_prot);
 -              }
 +      if (off < nr_pages && nr_vma_pages <= (nr_pages - off)) {
 +              ret = remap_pfn_range(vma, vma->vm_start,
 +                                    pfn + off,
 +                                    vma->vm_end - vma->vm_start,
 +                                    vma->vm_page_prot);
        }
  #endif        /* CONFIG_MMU */
  
        return ret;
  }
  
 -int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
 -                    void *cpu_addr, dma_addr_t dma_addr, size_t size)
 -{
 -      vma->vm_page_prot = pgprot_dmacoherent(vma->vm_page_prot);
 -      return dma_mmap(dev, vma, cpu_addr, dma_addr, size);
 -}
 -EXPORT_SYMBOL(dma_mmap_coherent);
 -
 -int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma,
 -                        void *cpu_addr, dma_addr_t dma_addr, size_t size)
 -{
 -      vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
 -      return dma_mmap(dev, vma, cpu_addr, dma_addr, size);
 -}
 -EXPORT_SYMBOL(dma_mmap_writecombine);
 -
  /*
 - * free a page as defined by the above mapping.
 - * Must not be called with IRQs disabled.
 + * Free a buffer as defined by the above mapping.
   */
 -void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle)
 +void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
 +                dma_addr_t handle, struct dma_attrs *attrs)
  {
 -      WARN_ON(irqs_disabled());
 +      struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
  
        if (dma_release_from_coherent(dev, get_order(size), cpu_addr))
                return;
  
        size = PAGE_ALIGN(size);
  
 -      if (!arch_is_coherent())
 +      if (arch_is_coherent() || nommu()) {
 +              __dma_free_buffer(page, size);
 +      } else if (__free_from_pool(cpu_addr, size)) {
 +              return;
 +      } else if (!IS_ENABLED(CONFIG_CMA)) {
                __dma_free_remap(cpu_addr, size);
 -
 -      __dma_free_buffer(pfn_to_page(dma_to_pfn(dev, handle)), size);
 -}
 -EXPORT_SYMBOL(dma_free_coherent);
 -
 -/*
 - * Make an area consistent for devices.
 - * Note: Drivers should NOT use this function directly, as it will break
 - * platforms with CONFIG_DMABOUNCE.
 - * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
 - */
 -void ___dma_single_cpu_to_dev(const void *kaddr, size_t size,
 -      enum dma_data_direction dir)
 -{
 -      unsigned long paddr;
 -
 -      BUG_ON(!virt_addr_valid(kaddr) || !virt_addr_valid(kaddr + size - 1));
 -
 -      dmac_map_area(kaddr, size, dir);
 -
 -      paddr = __pa(kaddr);
 -      if (dir == DMA_FROM_DEVICE) {
 -              outer_inv_range(paddr, paddr + size);
 +              __dma_free_buffer(page, size);
        } else {
 -              outer_clean_range(paddr, paddr + size);
 -      }
 -      /* FIXME: non-speculating: flush on bidirectional mappings? */
 -}
 -EXPORT_SYMBOL(___dma_single_cpu_to_dev);
 -
 -void ___dma_single_dev_to_cpu(const void *kaddr, size_t size,
 -      enum dma_data_direction dir)
 -{
 -      BUG_ON(!virt_addr_valid(kaddr) || !virt_addr_valid(kaddr + size - 1));
 -
 -      /* FIXME: non-speculating: not required */
 -      /* don't bother invalidating if DMA to device */
 -      if (dir != DMA_TO_DEVICE) {
 -              unsigned long paddr = __pa(kaddr);
 -              outer_inv_range(paddr, paddr + size);
 +              /*
 +               * Non-atomic allocations cannot be freed with IRQs disabled
 +               */
 +              WARN_ON(irqs_disabled());
 +              __free_from_contiguous(dev, page, size);
        }
 -
 -      dmac_unmap_area(kaddr, size, dir);
  }
 -EXPORT_SYMBOL(___dma_single_dev_to_cpu);
  
  static void dma_cache_maint_page(struct page *page, unsigned long offset,
        size_t size, enum dma_data_direction dir,
        } while (left);
  }
  
 -void ___dma_page_cpu_to_dev(struct page *page, unsigned long off,
 +/*
 + * Make an area consistent for devices.
 + * Note: Drivers should NOT use this function directly, as it will break
 + * platforms with CONFIG_DMABOUNCE.
 + * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
 + */
 +static void __dma_page_cpu_to_dev(struct page *page, unsigned long off,
        size_t size, enum dma_data_direction dir)
  {
        unsigned long paddr;
        }
        /* FIXME: non-speculating: flush on bidirectional mappings? */
  }
 -EXPORT_SYMBOL(___dma_page_cpu_to_dev);
  
 -void ___dma_page_dev_to_cpu(struct page *page, unsigned long off,
 +static void __dma_page_dev_to_cpu(struct page *page, unsigned long off,
        size_t size, enum dma_data_direction dir)
  {
        unsigned long paddr = page_to_phys(page) + off;
        dma_cache_maint_page(page, off, size, dir, dmac_unmap_area);
  
        /*
 -       * Mark the D-cache clean for this page to avoid extra flushing.
 +       * Mark the D-cache clean for these pages to avoid extra flushing.
         */
 -      if (dir != DMA_TO_DEVICE && off == 0 && size >= PAGE_SIZE)
 -              set_bit(PG_dcache_clean, &page->flags);
 +      if (dir != DMA_TO_DEVICE && size >= PAGE_SIZE) {
 +              unsigned long pfn;
 +              size_t left = size;
 +
 +              pfn = page_to_pfn(page) + off / PAGE_SIZE;
 +              off %= PAGE_SIZE;
 +              if (off) {
 +                      pfn++;
 +                      left -= PAGE_SIZE - off;
 +              }
 +              while (left >= PAGE_SIZE) {
 +                      page = pfn_to_page(pfn++);
 +                      set_bit(PG_dcache_clean, &page->flags);
 +                      left -= PAGE_SIZE;
 +              }
 +      }
  }
 -EXPORT_SYMBOL(___dma_page_dev_to_cpu);
  
  /**
 - * dma_map_sg - map a set of SG buffers for streaming mode DMA
 + * arm_dma_map_sg - map a set of SG buffers for streaming mode DMA
   * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
   * @sg: list of buffers
   * @nents: number of buffers to map
   * Device ownership issues as mentioned for dma_map_single are the same
   * here.
   */
 -int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 -              enum dma_data_direction dir)
 +int arm_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 +              enum dma_data_direction dir, struct dma_attrs *attrs)
  {
 +      struct dma_map_ops *ops = get_dma_ops(dev);
        struct scatterlist *s;
        int i, j;
  
 -      BUG_ON(!valid_dma_direction(dir));
 -
        for_each_sg(sg, s, nents, i) {
 -              s->dma_address = __dma_map_page(dev, sg_page(s), s->offset,
 -                                              s->length, dir);
 +#ifdef CONFIG_NEED_SG_DMA_LENGTH
 +              s->dma_length = s->length;
 +#endif
 +              s->dma_address = ops->map_page(dev, sg_page(s), s->offset,
 +                                              s->length, dir, attrs);
                if (dma_mapping_error(dev, s->dma_address))
                        goto bad_mapping;
        }
 -      debug_dma_map_sg(dev, sg, nents, nents, dir);
        return nents;
  
   bad_mapping:
        for_each_sg(sg, s, i, j)
 -              __dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
 +              ops->unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir, attrs);
        return 0;
  }
 -EXPORT_SYMBOL(dma_map_sg);
  
  /**
 - * dma_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg
 + * arm_dma_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg
   * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
   * @sg: list of buffers
   * @nents: number of buffers to unmap (same as was passed to dma_map_sg)
   * Unmap a set of streaming mode DMA translations.  Again, CPU access
   * rules concerning calls here are the same as for dma_unmap_single().
   */
 -void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
 -              enum dma_data_direction dir)
 +void arm_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
 +              enum dma_data_direction dir, struct dma_attrs *attrs)
  {
 +      struct dma_map_ops *ops = get_dma_ops(dev);
        struct scatterlist *s;
 -      int i;
  
 -      debug_dma_unmap_sg(dev, sg, nents, dir);
 +      int i;
  
        for_each_sg(sg, s, nents, i)
 -              __dma_unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir);
 +              ops->unmap_page(dev, sg_dma_address(s), sg_dma_len(s), dir, attrs);
  }
 -EXPORT_SYMBOL(dma_unmap_sg);
  
  /**
 - * dma_sync_sg_for_cpu
 + * arm_dma_sync_sg_for_cpu
   * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
   * @sg: list of buffers
   * @nents: number of buffers to map (returned from dma_map_sg)
   * @dir: DMA transfer direction (same as was passed to dma_map_sg)
   */
 -void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
 +void arm_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
                        int nents, enum dma_data_direction dir)
  {
 +      struct dma_map_ops *ops = get_dma_ops(dev);
        struct scatterlist *s;
        int i;
  
 -      for_each_sg(sg, s, nents, i) {
 -              if (!dmabounce_sync_for_cpu(dev, sg_dma_address(s), 0,
 -                                          sg_dma_len(s), dir))
 -                      continue;
 -
 -              __dma_page_dev_to_cpu(sg_page(s), s->offset,
 -                                    s->length, dir);
 -      }
 -
 -      debug_dma_sync_sg_for_cpu(dev, sg, nents, dir);
 +      for_each_sg(sg, s, nents, i)
 +              ops->sync_single_for_cpu(dev, sg_dma_address(s), s->length,
 +                                       dir);
  }
 -EXPORT_SYMBOL(dma_sync_sg_for_cpu);
  
  /**
 - * dma_sync_sg_for_device
 + * arm_dma_sync_sg_for_device
   * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
   * @sg: list of buffers
   * @nents: number of buffers to map (returned from dma_map_sg)
   * @dir: DMA transfer direction (same as was passed to dma_map_sg)
   */
 -void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
 +void arm_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
                        int nents, enum dma_data_direction dir)
  {
 +      struct dma_map_ops *ops = get_dma_ops(dev);
        struct scatterlist *s;
        int i;
  
 -      for_each_sg(sg, s, nents, i) {
 -              if (!dmabounce_sync_for_device(dev, sg_dma_address(s), 0,
 -                                      sg_dma_len(s), dir))
 -                      continue;
 -
 -              __dma_page_cpu_to_dev(sg_page(s), s->offset,
 -                                    s->length, dir);
 -      }
 -
 -      debug_dma_sync_sg_for_device(dev, sg, nents, dir);
 +      for_each_sg(sg, s, nents, i)
 +              ops->sync_single_for_device(dev, sg_dma_address(s), s->length,
 +                                          dir);
  }
 -EXPORT_SYMBOL(dma_sync_sg_for_device);
  
  /*
   * Return whether the given device DMA address mask can be supported
@@@ -877,15 -708,18 +877,15 @@@ int dma_supported(struct device *dev, u
  }
  EXPORT_SYMBOL(dma_supported);
  
 -int dma_set_mask(struct device *dev, u64 dma_mask)
 +static int arm_dma_set_mask(struct device *dev, u64 dma_mask)
  {
        if (!dev->dma_mask || !dma_supported(dev, dma_mask))
                return -EIO;
  
 -#ifndef CONFIG_DMABOUNCE
        *dev->dma_mask = dma_mask;
 -#endif
  
        return 0;
  }
 -EXPORT_SYMBOL(dma_set_mask);
  
  #define PREALLOC_DMA_DEBUG_ENTRIES    4096
  
@@@ -895,666 -729,3 +895,666 @@@ static int __init dma_debug_do_init(voi
        return 0;
  }
  fs_initcall(dma_debug_do_init);
 +
 +#ifdef CONFIG_ARM_DMA_USE_IOMMU
 +
 +/* IOMMU */
 +
 +static inline dma_addr_t __alloc_iova(struct dma_iommu_mapping *mapping,
 +                                    size_t size)
 +{
 +      unsigned int order = get_order(size);
 +      unsigned int align = 0;
 +      unsigned int count, start;
 +      unsigned long flags;
 +
 +      count = ((PAGE_ALIGN(size) >> PAGE_SHIFT) +
 +               (1 << mapping->order) - 1) >> mapping->order;
 +
 +      if (order > mapping->order)
 +              align = (1 << (order - mapping->order)) - 1;
 +
 +      spin_lock_irqsave(&mapping->lock, flags);
 +      start = bitmap_find_next_zero_area(mapping->bitmap, mapping->bits, 0,
 +                                         count, align);
 +      if (start > mapping->bits) {
 +              spin_unlock_irqrestore(&mapping->lock, flags);
 +              return DMA_ERROR_CODE;
 +      }
 +
 +      bitmap_set(mapping->bitmap, start, count);
 +      spin_unlock_irqrestore(&mapping->lock, flags);
 +
 +      return mapping->base + (start << (mapping->order + PAGE_SHIFT));
 +}
 +
 +static inline void __free_iova(struct dma_iommu_mapping *mapping,
 +                             dma_addr_t addr, size_t size)
 +{
 +      unsigned int start = (addr - mapping->base) >>
 +                           (mapping->order + PAGE_SHIFT);
 +      unsigned int count = ((size >> PAGE_SHIFT) +
 +                            (1 << mapping->order) - 1) >> mapping->order;
 +      unsigned long flags;
 +
 +      spin_lock_irqsave(&mapping->lock, flags);
 +      bitmap_clear(mapping->bitmap, start, count);
 +      spin_unlock_irqrestore(&mapping->lock, flags);
 +}
 +
 +static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, gfp_t gfp)
 +{
 +      struct page **pages;
 +      int count = size >> PAGE_SHIFT;
 +      int array_size = count * sizeof(struct page *);
 +      int i = 0;
 +
 +      if (array_size <= PAGE_SIZE)
 +              pages = kzalloc(array_size, gfp);
 +      else
 +              pages = vzalloc(array_size);
 +      if (!pages)
 +              return NULL;
 +
 +      while (count) {
 +              int j, order = __fls(count);
 +
 +              pages[i] = alloc_pages(gfp | __GFP_NOWARN, order);
 +              while (!pages[i] && order)
 +                      pages[i] = alloc_pages(gfp | __GFP_NOWARN, --order);
 +              if (!pages[i])
 +                      goto error;
 +
 +              if (order)
 +                      split_page(pages[i], order);
 +              j = 1 << order;
 +              while (--j)
 +                      pages[i + j] = pages[i] + j;
 +
 +              __dma_clear_buffer(pages[i], PAGE_SIZE << order);
 +              i += 1 << order;
 +              count -= 1 << order;
 +      }
 +
 +      return pages;
 +error:
 +      while (i--)
 +              if (pages[i])
 +                      __free_pages(pages[i], 0);
 +      if (array_size <= PAGE_SIZE)
 +              kfree(pages);
 +      else
 +              vfree(pages);
 +      return NULL;
 +}
 +
 +static int __iommu_free_buffer(struct device *dev, struct page **pages, size_t size)
 +{
 +      int count = size >> PAGE_SHIFT;
 +      int array_size = count * sizeof(struct page *);
 +      int i;
 +      for (i = 0; i < count; i++)
 +              if (pages[i])
 +                      __free_pages(pages[i], 0);
 +      if (array_size <= PAGE_SIZE)
 +              kfree(pages);
 +      else
 +              vfree(pages);
 +      return 0;
 +}
 +
 +/*
 + * Create a CPU mapping for a specified pages
 + */
 +static void *
 +__iommu_alloc_remap(struct page **pages, size_t size, gfp_t gfp, pgprot_t prot,
 +                  const void *caller)
 +{
 +      unsigned int i, nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
 +      struct vm_struct *area;
 +      unsigned long p;
 +
 +      area = get_vm_area_caller(size, VM_ARM_DMA_CONSISTENT | VM_USERMAP,
 +                                caller);
 +      if (!area)
 +              return NULL;
 +
 +      area->pages = pages;
 +      area->nr_pages = nr_pages;
 +      p = (unsigned long)area->addr;
 +
 +      for (i = 0; i < nr_pages; i++) {
 +              phys_addr_t phys = __pfn_to_phys(page_to_pfn(pages[i]));
 +              if (ioremap_page_range(p, p + PAGE_SIZE, phys, prot))
 +                      goto err;
 +              p += PAGE_SIZE;
 +      }
 +      return area->addr;
 +err:
 +      unmap_kernel_range((unsigned long)area->addr, size);
 +      vunmap(area->addr);
 +      return NULL;
 +}
 +
 +/*
 + * Create a mapping in device IO address space for specified pages
 + */
 +static dma_addr_t
 +__iommu_create_mapping(struct device *dev, struct page **pages, size_t size)
 +{
 +      struct dma_iommu_mapping *mapping = dev->archdata.mapping;
 +      unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
 +      dma_addr_t dma_addr, iova;
 +      int i, ret = DMA_ERROR_CODE;
 +
 +      dma_addr = __alloc_iova(mapping, size);
 +      if (dma_addr == DMA_ERROR_CODE)
 +              return dma_addr;
 +
 +      iova = dma_addr;
 +      for (i = 0; i < count; ) {
 +              unsigned int next_pfn = page_to_pfn(pages[i]) + 1;
 +              phys_addr_t phys = page_to_phys(pages[i]);
 +              unsigned int len, j;
 +
 +              for (j = i + 1; j < count; j++, next_pfn++)
 +                      if (page_to_pfn(pages[j]) != next_pfn)
 +                              break;
 +
 +              len = (j - i) << PAGE_SHIFT;
 +              ret = iommu_map(mapping->domain, iova, phys, len, 0);
 +              if (ret < 0)
 +                      goto fail;
 +              iova += len;
 +              i = j;
 +      }
 +      return dma_addr;
 +fail:
 +      iommu_unmap(mapping->domain, dma_addr, iova-dma_addr);
 +      __free_iova(mapping, dma_addr, size);
 +      return DMA_ERROR_CODE;
 +}
 +
 +static int __iommu_remove_mapping(struct device *dev, dma_addr_t iova, size_t size)
 +{
 +      struct dma_iommu_mapping *mapping = dev->archdata.mapping;
 +
 +      /*
 +       * add optional in-page offset from iova to size and align
 +       * result to page size
 +       */
 +      size = PAGE_ALIGN((iova & ~PAGE_MASK) + size);
 +      iova &= PAGE_MASK;
 +
 +      iommu_unmap(mapping->domain, iova, size);
 +      __free_iova(mapping, iova, size);
 +      return 0;
 +}
 +
 +static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs)
 +{
 +      struct vm_struct *area;
 +
 +      if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs))
 +              return cpu_addr;
 +
 +      area = find_vm_area(cpu_addr);
 +      if (area && (area->flags & VM_ARM_DMA_CONSISTENT))
 +              return area->pages;
 +      return NULL;
 +}
 +
 +static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
 +          dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
 +{
 +      pgprot_t prot = __get_dma_pgprot(attrs, pgprot_kernel);
 +      struct page **pages;
 +      void *addr = NULL;
 +
 +      *handle = DMA_ERROR_CODE;
 +      size = PAGE_ALIGN(size);
 +
 +      pages = __iommu_alloc_buffer(dev, size, gfp);
 +      if (!pages)
 +              return NULL;
 +
 +      *handle = __iommu_create_mapping(dev, pages, size);
 +      if (*handle == DMA_ERROR_CODE)
 +              goto err_buffer;
 +
 +      if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs))
 +              return pages;
 +
 +      addr = __iommu_alloc_remap(pages, size, gfp, prot,
 +                                 __builtin_return_address(0));
 +      if (!addr)
 +              goto err_mapping;
 +
 +      return addr;
 +
 +err_mapping:
 +      __iommu_remove_mapping(dev, *handle, size);
 +err_buffer:
 +      __iommu_free_buffer(dev, pages, size);
 +      return NULL;
 +}
 +
 +static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
 +                  void *cpu_addr, dma_addr_t dma_addr, size_t size,
 +                  struct dma_attrs *attrs)
 +{
 +      unsigned long uaddr = vma->vm_start;
 +      unsigned long usize = vma->vm_end - vma->vm_start;
 +      struct page **pages = __iommu_get_pages(cpu_addr, attrs);
 +
 +      vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
 +
 +      if (!pages)
 +              return -ENXIO;
 +
 +      do {
 +              int ret = vm_insert_page(vma, uaddr, *pages++);
 +              if (ret) {
 +                      pr_err("Remapping memory failed: %d\n", ret);
 +                      return ret;
 +              }
 +              uaddr += PAGE_SIZE;
 +              usize -= PAGE_SIZE;
 +      } while (usize > 0);
 +
 +      return 0;
 +}
 +
 +/*
 + * free a page as defined by the above mapping.
 + * Must not be called with IRQs disabled.
 + */
 +void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
 +                        dma_addr_t handle, struct dma_attrs *attrs)
 +{
 +      struct page **pages = __iommu_get_pages(cpu_addr, attrs);
 +      size = PAGE_ALIGN(size);
 +
 +      if (!pages) {
 +              WARN(1, "trying to free invalid coherent area: %p\n", cpu_addr);
 +              return;
 +      }
 +
 +      if (!dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs)) {
 +              unmap_kernel_range((unsigned long)cpu_addr, size);
 +              vunmap(cpu_addr);
 +      }
 +
 +      __iommu_remove_mapping(dev, handle, size);
 +      __iommu_free_buffer(dev, pages, size);
 +}
 +
 +/*
 + * Map a part of the scatter-gather list into contiguous io address space
 + */
 +static int __map_sg_chunk(struct device *dev, struct scatterlist *sg,
 +                        size_t size, dma_addr_t *handle,
 +                        enum dma_data_direction dir)
 +{
 +      struct dma_iommu_mapping *mapping = dev->archdata.mapping;
 +      dma_addr_t iova, iova_base;
 +      int ret = 0;
 +      unsigned int count;
 +      struct scatterlist *s;
 +
 +      size = PAGE_ALIGN(size);
 +      *handle = DMA_ERROR_CODE;
 +
 +      iova_base = iova = __alloc_iova(mapping, size);
 +      if (iova == DMA_ERROR_CODE)
 +              return -ENOMEM;
 +
 +      for (count = 0, s = sg; count < (size >> PAGE_SHIFT); s = sg_next(s)) {
 +              phys_addr_t phys = page_to_phys(sg_page(s));
 +              unsigned int len = PAGE_ALIGN(s->offset + s->length);
 +
 +              if (!arch_is_coherent())
 +                      __dma_page_cpu_to_dev(sg_page(s), s->offset, s->length, dir);
 +
 +              ret = iommu_map(mapping->domain, iova, phys, len, 0);
 +              if (ret < 0)
 +                      goto fail;
 +              count += len >> PAGE_SHIFT;
 +              iova += len;
 +      }
 +      *handle = iova_base;
 +
 +      return 0;
 +fail:
 +      iommu_unmap(mapping->domain, iova_base, count * PAGE_SIZE);
 +      __free_iova(mapping, iova_base, size);
 +      return ret;
 +}
 +
 +/**
 + * arm_iommu_map_sg - map a set of SG buffers for streaming mode DMA
 + * @dev: valid struct device pointer
 + * @sg: list of buffers
 + * @nents: number of buffers to map
 + * @dir: DMA transfer direction
 + *
 + * Map a set of buffers described by scatterlist in streaming mode for DMA.
 + * The scatter gather list elements are merged together (if possible) and
 + * tagged with the appropriate dma address and length. They are obtained via
 + * sg_dma_{address,length}.
 + */
 +int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 +                   enum dma_data_direction dir, struct dma_attrs *attrs)
 +{
 +      struct scatterlist *s = sg, *dma = sg, *start = sg;
 +      int i, count = 0;
 +      unsigned int offset = s->offset;
 +      unsigned int size = s->offset + s->length;
 +      unsigned int max = dma_get_max_seg_size(dev);
 +
 +      for (i = 1; i < nents; i++) {
 +              s = sg_next(s);
 +
 +              s->dma_address = DMA_ERROR_CODE;
 +              s->dma_length = 0;
 +
 +              if (s->offset || (size & ~PAGE_MASK) || size + s->length > max) {
 +                      if (__map_sg_chunk(dev, start, size, &dma->dma_address,
 +                          dir) < 0)
 +                              goto bad_mapping;
 +
 +                      dma->dma_address += offset;
 +                      dma->dma_length = size - offset;
 +
 +                      size = offset = s->offset;
 +                      start = s;
 +                      dma = sg_next(dma);
 +                      count += 1;
 +              }
 +              size += s->length;
 +      }
 +      if (__map_sg_chunk(dev, start, size, &dma->dma_address, dir) < 0)
 +              goto bad_mapping;
 +
 +      dma->dma_address += offset;
 +      dma->dma_length = size - offset;
 +
 +      return count+1;
 +
 +bad_mapping:
 +      for_each_sg(sg, s, count, i)
 +              __iommu_remove_mapping(dev, sg_dma_address(s), sg_dma_len(s));
 +      return 0;
 +}
 +
 +/**
 + * arm_iommu_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg
 + * @dev: valid struct device pointer
 + * @sg: list of buffers
 + * @nents: number of buffers to unmap (same as was passed to dma_map_sg)
 + * @dir: DMA transfer direction (same as was passed to dma_map_sg)
 + *
 + * Unmap a set of streaming mode DMA translations.  Again, CPU access
 + * rules concerning calls here are the same as for dma_unmap_single().
 + */
 +void arm_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
 +                      enum dma_data_direction dir, struct dma_attrs *attrs)
 +{
 +      struct scatterlist *s;
 +      int i;
 +
 +      for_each_sg(sg, s, nents, i) {
 +              if (sg_dma_len(s))
 +                      __iommu_remove_mapping(dev, sg_dma_address(s),
 +                                             sg_dma_len(s));
 +              if (!arch_is_coherent())
 +                      __dma_page_dev_to_cpu(sg_page(s), s->offset,
 +                                            s->length, dir);
 +      }
 +}
 +
 +/**
 + * arm_iommu_sync_sg_for_cpu
 + * @dev: valid struct device pointer
 + * @sg: list of buffers
 + * @nents: number of buffers to map (returned from dma_map_sg)
 + * @dir: DMA transfer direction (same as was passed to dma_map_sg)
 + */
 +void arm_iommu_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
 +                      int nents, enum dma_data_direction dir)
 +{
 +      struct scatterlist *s;
 +      int i;
 +
 +      for_each_sg(sg, s, nents, i)
 +              if (!arch_is_coherent())
 +                      __dma_page_dev_to_cpu(sg_page(s), s->offset, s->length, dir);
 +
 +}
 +
 +/**
 + * arm_iommu_sync_sg_for_device
 + * @dev: valid struct device pointer
 + * @sg: list of buffers
 + * @nents: number of buffers to map (returned from dma_map_sg)
 + * @dir: DMA transfer direction (same as was passed to dma_map_sg)
 + */
 +void arm_iommu_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
 +                      int nents, enum dma_data_direction dir)
 +{
 +      struct scatterlist *s;
 +      int i;
 +
 +      for_each_sg(sg, s, nents, i)
 +              if (!arch_is_coherent())
 +                      __dma_page_cpu_to_dev(sg_page(s), s->offset, s->length, dir);
 +}
 +
 +
 +/**
 + * arm_iommu_map_page
 + * @dev: valid struct device pointer
 + * @page: page that buffer resides in
 + * @offset: offset into page for start of buffer
 + * @size: size of buffer to map
 + * @dir: DMA transfer direction
 + *
 + * IOMMU aware version of arm_dma_map_page()
 + */
 +static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page,
 +           unsigned long offset, size_t size, enum dma_data_direction dir,
 +           struct dma_attrs *attrs)
 +{
 +      struct dma_iommu_mapping *mapping = dev->archdata.mapping;
 +      dma_addr_t dma_addr;
 +      int ret, len = PAGE_ALIGN(size + offset);
 +
 +      if (!arch_is_coherent())
 +              __dma_page_cpu_to_dev(page, offset, size, dir);
 +
 +      dma_addr = __alloc_iova(mapping, len);
 +      if (dma_addr == DMA_ERROR_CODE)
 +              return dma_addr;
 +
 +      ret = iommu_map(mapping->domain, dma_addr, page_to_phys(page), len, 0);
 +      if (ret < 0)
 +              goto fail;
 +
 +      return dma_addr + offset;
 +fail:
 +      __free_iova(mapping, dma_addr, len);
 +      return DMA_ERROR_CODE;
 +}
 +
 +/**
 + * arm_iommu_unmap_page
 + * @dev: valid struct device pointer
 + * @handle: DMA address of buffer
 + * @size: size of buffer (same as passed to dma_map_page)
 + * @dir: DMA transfer direction (same as passed to dma_map_page)
 + *
 + * IOMMU aware version of arm_dma_unmap_page()
 + */
 +static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle,
 +              size_t size, enum dma_data_direction dir,
 +              struct dma_attrs *attrs)
 +{
 +      struct dma_iommu_mapping *mapping = dev->archdata.mapping;
 +      dma_addr_t iova = handle & PAGE_MASK;
 +      struct page *page = phys_to_page(iommu_iova_to_phys(mapping->domain, iova));
 +      int offset = handle & ~PAGE_MASK;
 +      int len = PAGE_ALIGN(size + offset);
 +
 +      if (!iova)
 +              return;
 +
 +      if (!arch_is_coherent())
 +              __dma_page_dev_to_cpu(page, offset, size, dir);
 +
 +      iommu_unmap(mapping->domain, iova, len);
 +      __free_iova(mapping, iova, len);
 +}
 +
 +static void arm_iommu_sync_single_for_cpu(struct device *dev,
 +              dma_addr_t handle, size_t size, enum dma_data_direction dir)
 +{
 +      struct dma_iommu_mapping *mapping = dev->archdata.mapping;
 +      dma_addr_t iova = handle & PAGE_MASK;
 +      struct page *page = phys_to_page(iommu_iova_to_phys(mapping->domain, iova));
 +      unsigned int offset = handle & ~PAGE_MASK;
 +
 +      if (!iova)
 +              return;
 +
 +      if (!arch_is_coherent())
 +              __dma_page_dev_to_cpu(page, offset, size, dir);
 +}
 +
 +static void arm_iommu_sync_single_for_device(struct device *dev,
 +              dma_addr_t handle, size_t size, enum dma_data_direction dir)
 +{
 +      struct dma_iommu_mapping *mapping = dev->archdata.mapping;
 +      dma_addr_t iova = handle & PAGE_MASK;
 +      struct page *page = phys_to_page(iommu_iova_to_phys(mapping->domain, iova));
 +      unsigned int offset = handle & ~PAGE_MASK;
 +
 +      if (!iova)
 +              return;
 +
 +      __dma_page_cpu_to_dev(page, offset, size, dir);
 +}
 +
 +struct dma_map_ops iommu_ops = {
 +      .alloc          = arm_iommu_alloc_attrs,
 +      .free           = arm_iommu_free_attrs,
 +      .mmap           = arm_iommu_mmap_attrs,
 +
 +      .map_page               = arm_iommu_map_page,
 +      .unmap_page             = arm_iommu_unmap_page,
 +      .sync_single_for_cpu    = arm_iommu_sync_single_for_cpu,
 +      .sync_single_for_device = arm_iommu_sync_single_for_device,
 +
 +      .map_sg                 = arm_iommu_map_sg,
 +      .unmap_sg               = arm_iommu_unmap_sg,
 +      .sync_sg_for_cpu        = arm_iommu_sync_sg_for_cpu,
 +      .sync_sg_for_device     = arm_iommu_sync_sg_for_device,
 +};
 +
 +/**
 + * arm_iommu_create_mapping
 + * @bus: pointer to the bus holding the client device (for IOMMU calls)
 + * @base: start address of the valid IO address space
 + * @size: size of the valid IO address space
 + * @order: accuracy of the IO addresses allocations
 + *
 + * Creates a mapping structure which holds information about used/unused
 + * IO address ranges, which is required to perform memory allocation and
 + * mapping with IOMMU aware functions.
 + *
 + * The client device need to be attached to the mapping with
 + * arm_iommu_attach_device function.
 + */
 +struct dma_iommu_mapping *
 +arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size,
 +                       int order)
 +{
 +      unsigned int count = size >> (PAGE_SHIFT + order);
 +      unsigned int bitmap_size = BITS_TO_LONGS(count) * sizeof(long);
 +      struct dma_iommu_mapping *mapping;
 +      int err = -ENOMEM;
 +
 +      if (!count)
 +              return ERR_PTR(-EINVAL);
 +
 +      mapping = kzalloc(sizeof(struct dma_iommu_mapping), GFP_KERNEL);
 +      if (!mapping)
 +              goto err;
 +
 +      mapping->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
 +      if (!mapping->bitmap)
 +              goto err2;
 +
 +      mapping->base = base;
 +      mapping->bits = BITS_PER_BYTE * bitmap_size;
 +      mapping->order = order;
 +      spin_lock_init(&mapping->lock);
 +
 +      mapping->domain = iommu_domain_alloc(bus);
 +      if (!mapping->domain)
 +              goto err3;
 +
 +      kref_init(&mapping->kref);
 +      return mapping;
 +err3:
 +      kfree(mapping->bitmap);
 +err2:
 +      kfree(mapping);
 +err:
 +      return ERR_PTR(err);
 +}
 +
 +static void release_iommu_mapping(struct kref *kref)
 +{
 +      struct dma_iommu_mapping *mapping =
 +              container_of(kref, struct dma_iommu_mapping, kref);
 +
 +      iommu_domain_free(mapping->domain);
 +      kfree(mapping->bitmap);
 +      kfree(mapping);
 +}
 +
 +void arm_iommu_release_mapping(struct dma_iommu_mapping *mapping)
 +{
 +      if (mapping)
 +              kref_put(&mapping->kref, release_iommu_mapping);
 +}
 +
 +/**
 + * arm_iommu_attach_device
 + * @dev: valid struct device pointer
 + * @mapping: io address space mapping structure (returned from
 + *    arm_iommu_create_mapping)
 + *
 + * Attaches specified io address space mapping to the provided device,
 + * this replaces the dma operations (dma_map_ops pointer) with the
 + * IOMMU aware version. More than one client might be attached to
 + * the same io address space mapping.
 + */
 +int arm_iommu_attach_device(struct device *dev,
 +                          struct dma_iommu_mapping *mapping)
 +{
 +      int err;
 +
 +      err = iommu_attach_device(mapping->domain, dev);
 +      if (err)
 +              return err;
 +
 +      kref_get(&mapping->kref);
 +      dev->archdata.mapping = mapping;
 +      set_dma_ops(dev, &iommu_ops);
 +
 +      pr_info("Attached IOMMU controller to %s device.\n", dev_name(dev));
 +      return 0;
 +}
 +
 +#endif
diff --combined drivers/hid/hid-core.c
@@@ -989,6 -989,7 +989,7 @@@ static void hid_input_field(struct hid_
                /* Ignore report if ErrorRollOver */
                if (!(field->flags & HID_MAIN_ITEM_VARIABLE) &&
                    value[n] >= min && value[n] <= max &&
+                   value[n] - min < field->maxusage &&
                    field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1)
                        goto exit;
        }
                }
  
                if (field->value[n] >= min && field->value[n] <= max
+                       && field->value[n] - min < field->maxusage
                        && field->usage[field->value[n] - min].hid
                        && search(value, field->value[n], count))
                                hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt);
  
                if (value[n] >= min && value[n] <= max
+                       && value[n] - min < field->maxusage
                        && field->usage[value[n] - min].hid
                        && search(field->value, value[n], count))
                                hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt);
@@@ -1537,7 -1540,6 +1540,7 @@@ static const struct hid_device_id hid_h
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DUAL_ACTION) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) },
diff --combined drivers/hid/hid-ids.h
  #define USB_DEVICE_ID_ATEN_2PORTKVM   0x2204
  #define USB_DEVICE_ID_ATEN_4PORTKVM   0x2205
  #define USB_DEVICE_ID_ATEN_4PORTKVMC  0x2208
+ #define USB_DEVICE_ID_ATEN_CS682      0x2213
+ #define USB_DEVICE_ID_ATEN_CS692      0x8021
  
  #define USB_VENDOR_ID_ATMEL           0x03eb
  #define USB_DEVICE_ID_ATMEL_MULTITOUCH        0x211c
  #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD 0xc20a
  #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD      0xc211
  #define USB_DEVICE_ID_LOGITECH_EXTREME_3D     0xc215
 +#define USB_DEVICE_ID_LOGITECH_DUAL_ACTION    0xc216
  #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2     0xc218
  #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2   0xc219
  #define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D    0xc283
diff --combined drivers/mmc/card/block.c
@@@ -119,7 -119,6 +119,7 @@@ enum mmc_blk_status 
        MMC_BLK_ABORT,
        MMC_BLK_DATA_ERR,
        MMC_BLK_ECC_ERR,
 +      MMC_BLK_NOMEDIUM,
  };
  
  module_param(perdev_minors, int, 0444);
@@@ -319,7 -318,7 +319,7 @@@ static int mmc_blk_ioctl_cmd(struct blo
        md = mmc_blk_get(bdev->bd_disk);
        if (!md) {
                err = -EINVAL;
 -              goto cmd_done;
 +              goto cmd_err;
        }
  
        card = md->queue.card;
@@@ -418,7 -417,6 +418,7 @@@ cmd_rel_host
  
  cmd_done:
        mmc_blk_put(md);
 +cmd_err:
        kfree(idata->buf);
        kfree(idata);
        return err;
@@@ -489,6 -487,7 +489,6 @@@ static u32 mmc_sd_num_wr_blocks(struct 
        struct mmc_request mrq = {NULL};
        struct mmc_command cmd = {0};
        struct mmc_data data = {0};
 -      unsigned int timeout_us;
  
        struct scatterlist sg;
  
        cmd.arg = 0;
        cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
  
 -      data.timeout_ns = card->csd.tacc_ns * 100;
 -      data.timeout_clks = card->csd.tacc_clks * 100;
 -
 -      timeout_us = data.timeout_ns / 1000;
 -      timeout_us += data.timeout_clks * 1000 /
 -              (card->host->ios.clock / 1000);
 -
 -      if (timeout_us > 100000) {
 -              data.timeout_ns = 100000000;
 -              data.timeout_clks = 0;
 -      }
 -
        data.blksz = 4;
        data.blocks = 1;
        data.flags = MMC_DATA_READ;
        data.sg = &sg;
        data.sg_len = 1;
 +      mmc_set_data_timeout(&data, card);
  
        mrq.cmd = &cmd;
        mrq.data = &data;
@@@ -563,7 -573,6 +563,7 @@@ static int get_card_status(struct mmc_c
        return err;
  }
  
 +#define ERR_NOMEDIUM  3
  #define ERR_RETRY     2
  #define ERR_ABORT     1
  #define ERR_CONTINUE  0
@@@ -631,9 -640,6 +631,9 @@@ static int mmc_blk_cmd_recovery(struct 
        u32 status, stop_status = 0;
        int err, retry;
  
 +      if (mmc_card_removed(card))
 +              return ERR_NOMEDIUM;
 +
        /*
         * Try to get card status which indicates both the card state
         * and why there was no response.  If the first attempt fails,
        }
  
        /* We couldn't get a response from the card.  Give up. */
 -      if (err)
 +      if (err) {
 +              /* Check if the card is removed */
 +              if (mmc_detect_card_removed(card->host))
 +                      return ERR_NOMEDIUM;
                return ERR_ABORT;
 +      }
  
        /* Flag ECC errors */
        if ((status & R1_CARD_ECC_FAILED) ||
@@@ -802,7 -804,9 +802,7 @@@ out
                goto retry;
        if (!err)
                mmc_blk_reset_success(md, type);
 -      spin_lock_irq(&md->lock);
 -      __blk_end_request(req, err, blk_rq_bytes(req));
 -      spin_unlock_irq(&md->lock);
 +      blk_end_request(req, err, blk_rq_bytes(req));
  
        return err ? 0 : 1;
  }
@@@ -884,7 -888,9 +884,7 @@@ out_retry
        if (!err)
                mmc_blk_reset_success(md, type);
  out:
 -      spin_lock_irq(&md->lock);
 -      __blk_end_request(req, err, blk_rq_bytes(req));
 -      spin_unlock_irq(&md->lock);
 +      blk_end_request(req, err, blk_rq_bytes(req));
  
        return err ? 0 : 1;
  }
@@@ -899,7 -905,9 +899,7 @@@ static int mmc_blk_issue_flush(struct m
        if (ret)
                ret = -EIO;
  
 -      spin_lock_irq(&md->lock);
 -      __blk_end_request_all(req, ret);
 -      spin_unlock_irq(&md->lock);
 +      blk_end_request_all(req, ret);
  
        return ret ? 0 : 1;
  }
@@@ -961,8 -969,6 +961,8 @@@ static int mmc_blk_err_check(struct mmc
                        return MMC_BLK_RETRY;
                case ERR_ABORT:
                        return MMC_BLK_ABORT;
 +              case ERR_NOMEDIUM:
 +                      return MMC_BLK_NOMEDIUM;
                case ERR_CONTINUE:
                        break;
                }
@@@ -1211,10 -1217,14 +1211,10 @@@ static int mmc_blk_cmd_err(struct mmc_b
  
                blocks = mmc_sd_num_wr_blocks(card);
                if (blocks != (u32)-1) {
 -                      spin_lock_irq(&md->lock);
 -                      ret = __blk_end_request(req, 0, blocks << 9);
 -                      spin_unlock_irq(&md->lock);
 +                      ret = blk_end_request(req, 0, blocks << 9);
                }
        } else {
 -              spin_lock_irq(&md->lock);
 -              ret = __blk_end_request(req, 0, brq->data.bytes_xfered);
 -              spin_unlock_irq(&md->lock);
 +              ret = blk_end_request(req, 0, brq->data.bytes_xfered);
        }
        return ret;
  }
@@@ -1256,8 -1266,10 +1256,8 @@@ static int mmc_blk_issue_rw_rq(struct m
                         * A block was successfully transferred.
                         */
                        mmc_blk_reset_success(md, type);
 -                      spin_lock_irq(&md->lock);
 -                      ret = __blk_end_request(req, 0,
 +                      ret = blk_end_request(req, 0,
                                                brq->data.bytes_xfered);
 -                      spin_unlock_irq(&md->lock);
                        /*
                         * If the blk_end_request function returns non-zero even
                         * though all data has been transferred and no errors
                         * time, so we only reach here after trying to
                         * read a single sector.
                         */
 -                      spin_lock_irq(&md->lock);
 -                      ret = __blk_end_request(req, -EIO,
 +                      ret = blk_end_request(req, -EIO,
                                                brq->data.blksz);
 -                      spin_unlock_irq(&md->lock);
                        if (!ret)
                                goto start_new_req;
                        break;
 +              case MMC_BLK_NOMEDIUM:
 +                      goto cmd_abort;
                }
  
                if (ret) {
        return 1;
  
   cmd_abort:
 -      spin_lock_irq(&md->lock);
 +      if (mmc_card_removed(card))
 +              req->cmd_flags |= REQ_QUIET;
        while (ret)
 -              ret = __blk_end_request(req, -EIO, blk_rq_cur_bytes(req));
 -      spin_unlock_irq(&md->lock);
 +              ret = blk_end_request(req, -EIO, blk_rq_cur_bytes(req));
  
   start_new_req:
        if (rqc) {
 -              mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq);
 -              mmc_start_req(card->host, &mq->mqrq_cur->mmc_active, NULL);
 +              if (mmc_card_removed(card)) {
 +                      rqc->cmd_flags |= REQ_QUIET;
 +                      blk_end_request_all(rqc, -EIO);
 +              } else {
 +                      mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq);
 +                      mmc_start_req(card->host,
 +                                    &mq->mqrq_cur->mmc_active, NULL);
 +              }
        }
  
        return 0;
@@@ -1364,7 -1370,9 +1364,7 @@@ static int mmc_blk_issue_rq(struct mmc_
        ret = mmc_blk_part_switch(card, md);
        if (ret) {
                if (req) {
 -                      spin_lock_irq(&md->lock);
 -                      __blk_end_request_all(req, -EIO);
 -                      spin_unlock_irq(&md->lock);
 +                      blk_end_request_all(req, -EIO);
                }
                ret = 0;
                goto out;
@@@ -1485,7 -1493,8 +1485,8 @@@ static struct mmc_blk_data *mmc_blk_all
        set_capacity(md->disk, size);
  
        if (mmc_host_cmd23(card->host)) {
-               if (mmc_card_mmc(card) ||
+               if ((mmc_card_mmc(card) &&
+                    card->csd.mmca_vsn >= CSD_SPEC_VER_3) ||
                    (mmc_card_sd(card) &&
                     card->scr.cmds & SD_SCR_CMD23_SUPPORT))
                        md->flags |= MMC_BLK_CMD23;
@@@ -1767,7 -1776,7 +1768,7 @@@ static void mmc_blk_remove(struct mmc_c
  }
  
  #ifdef CONFIG_PM
 -static int mmc_blk_suspend(struct mmc_card *card, pm_message_t state)
 +static int mmc_blk_suspend(struct mmc_card *card)
  {
        struct mmc_blk_data *part_md;
        struct mmc_blk_data *md = mmc_get_drvdata(card);
diff --combined drivers/mtd/ubi/upd.c
@@@ -150,11 -150,11 +150,11 @@@ int ubi_start_update(struct ubi_device 
                        return err;
        }
  
-       if (bytes == 0) {
-               err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL);
-               if (err)
-                       return err;
 -      err = ubi_wl_flush(ubi);
++      err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL);
+       if (err)
+               return err;
  
+       if (bytes == 0) {
                err = clear_update_marker(ubi, vol, 0);
                if (err)
                        return err;
@@@ -188,12 -188,14 +188,12 @@@ int ubi_start_leb_change(struct ubi_dev
        dbg_gen("start changing LEB %d:%d, %u bytes",
                vol->vol_id, req->lnum, req->bytes);
        if (req->bytes == 0)
 -              return ubi_eba_atomic_leb_change(ubi, vol, req->lnum, NULL, 0,
 -                                               req->dtype);
 +              return ubi_eba_atomic_leb_change(ubi, vol, req->lnum, NULL, 0);
  
        vol->upd_bytes = req->bytes;
        vol->upd_received = 0;
        vol->changing_leb = 1;
        vol->ch_lnum = req->lnum;
 -      vol->ch_dtype = req->dtype;
  
        vol->upd_buf = vmalloc(ALIGN((int)req->bytes, ubi->min_io_size));
        if (!vol->upd_buf)
@@@ -246,7 -248,8 +246,7 @@@ static int write_leb(struct ubi_device 
                        return 0;
                }
  
 -              err = ubi_eba_write_leb(ubi, vol, lnum, buf, 0, len,
 -                                      UBI_UNKNOWN);
 +              err = ubi_eba_write_leb(ubi, vol, lnum, buf, 0, len);
        } else {
                /*
                 * When writing static volume, and this is the last logical
                 * contain zeros, not random trash.
                 */
                memset(buf + len, 0, vol->usable_leb_size - len);
 -              err = ubi_eba_write_leb_st(ubi, vol, lnum, buf, len,
 -                                         UBI_UNKNOWN, used_ebs);
 +              err = ubi_eba_write_leb_st(ubi, vol, lnum, buf, len, used_ebs);
        }
  
        return err;
@@@ -363,7 -367,7 +363,7 @@@ int ubi_more_update_data(struct ubi_dev
  
        ubi_assert(vol->upd_received <= vol->upd_bytes);
        if (vol->upd_received == vol->upd_bytes) {
 -              err = ubi_wl_flush(ubi);
 +              err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL);
                if (err)
                        return err;
                /* The update is finished, clear the update marker */
@@@ -419,7 -423,7 +419,7 @@@ int ubi_more_leb_change_data(struct ubi
                       len - vol->upd_bytes);
                len = ubi_calc_data_len(ubi, vol->upd_buf, len);
                err = ubi_eba_atomic_leb_change(ubi, vol, vol->ch_lnum,
 -                                              vol->upd_buf, len, UBI_UNKNOWN);
 +                                              vol->upd_buf, len);
                if (err)
                        return err;
        }
@@@ -640,7 -640,6 +640,7 @@@ fail
                priv->iv = kmemdup(iv, nr_segs * sizeof(struct iovec),
                                   GFP_KERNEL);
                if (!priv->iv) {
 +                      value = -ENOMEM;
                        kfree(priv);
                        goto fail;
                }
@@@ -1197,7 -1196,7 +1197,7 @@@ ep0_write (struct file *fd, const char 
        /* data and/or status stage for control request */
        } else if (dev->state == STATE_DEV_SETUP) {
  
-               /* IN DATA+STATUS caller makes len <= wLength */
+               len = min_t(size_t, len, dev->setup_wLength);
                if (dev->setup_in) {
                        retval = setup_req (dev->gadget->ep0, dev->req, len);
                        if (retval == 0) {
@@@ -1842,10 -1841,12 +1842,12 @@@ static struct usb_gadget_driver probe_d
   * such as configuration notifications.
   */
  
- static int is_valid_config (struct usb_config_descriptor *config)
+ static int is_valid_config(struct usb_config_descriptor *config,
+               unsigned int total)
  {
        return config->bDescriptorType == USB_DT_CONFIG
                && config->bLength == USB_DT_CONFIG_SIZE
+               && total >= USB_DT_CONFIG_SIZE
                && config->bConfigurationValue != 0
                && (config->bmAttributes & USB_CONFIG_ATT_ONE) != 0
                && (config->bmAttributes & USB_CONFIG_ATT_WAKEUP) == 0;
@@@ -1862,7 -1863,8 +1864,8 @@@ dev_config (struct file *fd, const cha
        u32                     tag;
        char                    *kbuf;
  
-       if (len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4))
+       if ((len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4)) ||
+           (len > PAGE_SIZE * 4))
                return -EINVAL;
  
        /* we might need to change message format someday */
        /* full or low speed config */
        dev->config = (void *) kbuf;
        total = le16_to_cpu(dev->config->wTotalLength);
-       if (!is_valid_config (dev->config) || total >= length)
+       if (!is_valid_config(dev->config, total) ||
+                       total > length - USB_DT_DEVICE_SIZE)
                goto fail;
        kbuf += total;
        length -= total;
        if (kbuf [1] == USB_DT_CONFIG) {
                dev->hs_config = (void *) kbuf;
                total = le16_to_cpu(dev->hs_config->wTotalLength);
-               if (!is_valid_config (dev->hs_config) || total >= length)
+               if (!is_valid_config(dev->hs_config, total) ||
+                               total > length - USB_DT_DEVICE_SIZE)
                        goto fail;
                kbuf += total;
                length -= total;
+       } else {
+               dev->hs_config = NULL;
        }
  
        /* could support multiple configs, using another encoding! */
diff --combined fs/exec.c
+++ b/fs/exec.c
@@@ -25,6 -25,7 +25,7 @@@
  #include <linux/slab.h>
  #include <linux/file.h>
  #include <linux/fdtable.h>
+ #include <linux/freezer.h>
  #include <linux/mm.h>
  #include <linux/stat.h>
  #include <linux/fcntl.h>
@@@ -207,8 -208,26 +208,26 @@@ static struct page *get_arg_page(struc
  
        if (write) {
                unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start;
+               unsigned long ptr_size;
                struct rlimit *rlim;
  
+               /*
+                * Since the stack will hold pointers to the strings, we
+                * must account for them as well.
+                *
+                * The size calculation is the entire vma while each arg page is
+                * built, so each time we get here it's calculating how far it
+                * is currently (rather than each call being just the newly
+                * added size from the arg page).  As a result, we need to
+                * always add the entire size of the pointers, so that on the
+                * last call to get_arg_page() we'll actually have the entire
+                * correct size.
+                */
+               ptr_size = (bprm->argc + bprm->envc) * sizeof(void *);
+               if (ptr_size > ULONG_MAX - size)
+                       goto fail;
+               size += ptr_size;
                acct_arg_size(bprm, size / PAGE_SIZE);
  
                /*
                 *    to work from.
                 */
                rlim = current->signal->rlim;
-               if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur) / 4) {
-                       put_page(page);
-                       return NULL;
-               }
+               if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur) / 4)
+                       goto fail;
        }
  
        return page;
+ fail:
+       put_page(page);
+       return NULL;
  }
  
  static void put_arg_page(struct page *page)
@@@ -1974,8 -1995,11 +1995,11 @@@ static int coredump_wait(int exit_code
                complete(vfork_done);
        }
  
-       if (core_waiters)
+       if (core_waiters > 0) {
+               freezer_do_not_count();
                wait_for_completion(&core_state->startup);
+               freezer_count();
+       }
  fail:
        return core_waiters;
  }
@@@ -2118,8 -2142,8 +2142,8 @@@ static int umh_pipe_setup(struct subpro
        fd_install(0, rp);
        spin_lock(&cf->file_lock);
        fdt = files_fdtable(cf);
 -      FD_SET(0, fdt->open_fds);
 -      FD_CLR(0, fdt->close_on_exec);
 +      __set_open_fd(0, fdt);
 +      __clear_close_on_exec(0, fdt);
        spin_unlock(&cf->file_lock);
  
        /* and disallow core files too */
diff --combined fs/proc/task_mmu.c
@@@ -210,196 -210,6 +210,196 @@@ static int do_maps_open(struct inode *i
        return ret;
  }
  
 +#ifdef __arm__
 +static void show_arm_map_vma(struct seq_file *m, struct vm_area_struct *vma)
 +{
 +      static const char *cache_attrs4[4] = { "noC", "WB-WA", "WT-noWA", "WB-noWA" };
 +      struct mm_struct *mm = vma->vm_mm;
 +      struct file *file = vma->vm_file;
 +      vm_flags_t flags = vma->vm_flags;
 +      unsigned long start, end, end_b;
 +      const char *name = NULL;
 +      u32 *arm_pgd;
 +      u32 *cpt, *cpt_e;
 +      u32 desc1, desc2;
 +      u32 tex_cb = 0;
 +      u32 prrr, nmrr = 0;
 +      u32 control = 0;
 +      u32 xn = 1, ap = 0;
 +      int desc_type;
 +      int type;
 +      char buf[64];
 +      char rw[4];
 +      int len;
 +      int s;
 +
 +      if (mm == NULL)
 +              return;
 +
 +      if (!file) {
 +              name = arch_vma_name(vma);
 +              if (!name) {
 +                      if (vma->vm_start <= mm->brk &&
 +                                      vma->vm_end >= mm->start_brk) {
 +                              name = "[heap]";
 +                      } else if (vma->vm_start <= mm->start_stack &&
 +                                 vma->vm_end >= mm->start_stack) {
 +                              name = "[stack]";
 +                      }
 +              }
 +      }
 +
 +      arm_pgd = (u32 *)mm->pgd;
 +
 +      asm ("mrc p15, 0, %0, c1, c0, 0" : "=r"(control));
 +      asm ("mrc p15, 0, %0, c10, c2, 0" : "=r"(prrr)); // primary region RR
 +      asm ("mrc p15, 0, %0, c10, c2, 1" : "=r"(nmrr)); // normal memory RR
 +
 +      start = vma->vm_start;
 +      end = vma->vm_end;
 +
 +      while (start < end) {
 +              desc_type = '-';
 +
 +              desc1 = arm_pgd[start >> 20];
 +
 +              end_b = (start & ~0xfffff) + 0x100000;
 +              for (; end_b < end; end_b += 0x100000)
 +                      if ((arm_pgd[end_b >> 20] ^ desc1) & 0xfffff)
 +                              break;
 +
 +              switch (desc1 & 3) {
 +              case 0:
 +                      sprintf(buf, "l1_fault");
 +                      goto do_output;
 +              case 1:
 +                      break;
 +              case 2:
 +                      tex_cb = ((desc1 >> 2) & 0x03) | ((desc1 >> 10) & 0x1c);
 +                      s = (desc1 >> 16) & 1;
 +                      xn = (desc1 >> 4) & 1;
 +                      ap = ((desc1 >> 10) & 3) | ((desc1 >> 13) & 4);
 +                      desc_type = (desc1 & (1 << 18)) ? 's' : 'h';
 +                      goto do_tex_cb;
 +              case 3:
 +                      sprintf(buf, "reserved");
 +                      goto do_output;
 +              }
 +
 +              cpt = __va(desc1 & 0xfffffc00);
 +              desc2 = cpt[(start >> 12) & 0xff];
 +
 +              // find end
 +              cpt_e = cpt;
 +              for (end_b = start + 0x1000; end_b < end; end_b += 0x1000) {
 +                      if ((end_b & 0x000ff000) == 0) {
 +                              cpt_e = __va(arm_pgd[end_b >> 20] & 0xfffffc00);
 +                              if ((arm_pgd[end_b >> 20] ^ desc1) & 0x3ff)
 +                                      break;
 +                      }
 +
 +                      // assume small pages
 +                      if ((cpt_e[(end_b >> 12) & 0xff] ^ desc2) & 0xfff)
 +                              break;
 +              }
 +
 +              switch (desc2 & 3) {
 +              case 0:
 +                      sprintf(buf, "l2_fault");
 +                      goto do_output;
 +              case 1:
 +                      tex_cb = ((desc2 >> 2) & 0x03) | ((desc2 >> 10) & 0x1c);
 +                      s = (desc2 >> 10) & 1;
 +                      xn = (desc2 >> 15) & 1;
 +                      ap = ((desc2 >> 4) & 3) | ((desc2 >> 7) & 4);
 +                      break;
 +              case 2:
 +              case 3:
 +                      tex_cb = ((desc2 >> 2) & 0x03) | ((desc2 >> 4) & 0x1c);
 +                      s = (desc2 >> 10) & 1;
 +                      xn = desc2 & 1;
 +                      ap = ((desc2 >> 4) & 3) | ((desc2 >> 7) & 4);
 +                      break;
 +              }
 +
 +do_tex_cb:
 +              if (control & (1 << 28)) { // TEX remap
 +                      // S (shareable) bit remapping
 +                      char s_normal[2] = { (prrr >> 18) & 1, (prrr >> 19) & 1 };
 +                      char s_device[2] = { (prrr >> 16) & 1, (prrr >> 17) & 1 };
 +
 +                      buf[0] = 0;
 +                      tex_cb &= 7;
 +                      type = (prrr >> tex_cb * 2) & 3;
 +                      switch (type) {
 +                      case 0:
 +                              sprintf(buf, "strongly-ordered");
 +                              break;
 +                      case 1:
 +                              sprintf(buf, "device");
 +                              s = s_device[s];
 +                              break;
 +                      case 3:
 +                              sprintf(buf, "reserved/normal");
 +                      case 2:
 +                              s = s_normal[s];
 +                              sprintf(buf + strlen(buf), "inner-%s-outer-%s",
 +                                      cache_attrs4[(nmrr >> tex_cb * 2) & 3],
 +                                      cache_attrs4[(nmrr >> (tex_cb * 2 + 16)) & 3]);
 +                      }
 +              }
 +              else if (tex_cb & 0x10) { // TEX[2] set
 +                      sprintf(buf, "inner-%s-outer-%s",
 +                              cache_attrs4[tex_cb & 3], cache_attrs4[(tex_cb >> 2) & 3]);
 +              }
 +              else {
 +                      switch (tex_cb) {
 +                      case 0x00: sprintf(buf, "strongly-ordered"); s = 1; break;
 +                      case 0x01: sprintf(buf, "shareable-device"); s = 1; break;
 +                      case 0x02: sprintf(buf, "inner-outer-WT-noWA"); break;
 +                      case 0x03: sprintf(buf, "inner-outer-WB-noWA"); break;
 +                      case 0x04: sprintf(buf, "inner-outer-non-cacheable"); break;
 +                      case 0x06: sprintf(buf, "implementation-defined"); break;
 +                      case 0x07: sprintf(buf, "inner-outer-WB-WA"); break;
 +                      case 0x08: sprintf(buf, "non-shareable-device"); s = 0; break;
 +                      default:   sprintf(buf, "reserved"); break;
 +                      }
 +              }
 +
 +              if (s)
 +                      sprintf(buf + strlen(buf), "-shareable");
 +
 +do_output:
 +              // use user permissions here
 +              if (control & (1 << 29)) // AFE
 +                      sprintf(rw, "%c%c", (ap & 2) ? 'r' : '-',
 +                              ((ap & 2) && !(ap & 4)) ? 'w' : '-');
 +              else
 +                      sprintf(rw, "%c%c", (ap & 2) ? 'r' : '-',
 +                              (ap == 3) ? 'w' : '-');
 +
 +              seq_printf(m, "%08lx-%08lx %s%c%c%c %-28s %n",
 +                              start, end_b,
 +                              rw,
 +                              xn ? '-' : 'x',
 +                              flags & VM_MAYSHARE ? 's' : 'p',
 +                              desc_type,
 +                              buf, &len);
 +
 +              if (file) {
 +                      pad_len_spaces(m, len);
 +                      seq_path(m, &file->f_path, "\n");
 +              } else if (name) {
 +                      pad_len_spaces(m, len);
 +                      seq_puts(m, name);
 +              }
 +              seq_putc(m, '\n');
 +
 +              start = end_b;
 +      }
 +}
 +#endif
 +
  static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
  {
        struct mm_struct *mm = vma->vm_mm;
  
        /* We don't show the stack guard page in /proc/maps */
        start = vma->vm_start;
-       if (stack_guard_page_start(vma, start))
-               start += PAGE_SIZE;
        end = vma->vm_end;
-       if (stack_guard_page_end(vma, end))
-               end -= PAGE_SIZE;
  
        seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n",
                        start,
@@@ -499,41 -305,6 +495,41 @@@ const struct file_operations proc_maps_
        .release        = seq_release_private,
  };
  
 +#ifdef __arm__
 +static int show_armv7_map(struct seq_file *m, void *v)
 +{
 +      struct vm_area_struct *vma = v;
 +      struct proc_maps_private *priv = m->private;
 +      struct task_struct *task = priv->task;
 +
 +      show_arm_map_vma(m, vma);
 +
 +      if (m->count < m->size)  /* vma is copied successfully */
 +              m->version = (vma != get_gate_vma(task->mm))
 +                      ? vma->vm_start : 0;
 +      return 0;
 +}
 +
 +static const struct seq_operations proc_pid_armv7_maps_op = {
 +      .start  = m_start,
 +      .next   = m_next,
 +      .stop   = m_stop,
 +      .show   = show_armv7_map
 +};
 +#endif
 +
 +static int armv7_maps_open(struct inode *inode, struct file *file)
 +{
 +      return do_maps_open(inode, file, &proc_pid_armv7_maps_op);
 +}
 +
 +const struct file_operations proc_armv7_maps_operations = {
 +      .open           = armv7_maps_open,
 +      .read           = seq_read,
 +      .llseek         = seq_lseek,
 +      .release        = seq_release_private,
 +};
 +
  /*
   * Proportional Set Size(PSS): my share of RSS.
   *
diff --combined fs/splice.c
@@@ -214,6 -214,7 +214,7 @@@ ssize_t splice_to_pipe(struct pipe_inod
                        buf->len = spd->partial[page_nr].len;
                        buf->private = spd->partial[page_nr].private;
                        buf->ops = spd->ops;
+                       buf->flags = 0;
                        if (spd->flags & SPLICE_F_GIFT)
                                buf->flags |= PIPE_BUF_FLAG_GIFT;
  
@@@ -1127,8 -1128,8 +1128,8 @@@ EXPORT_SYMBOL(generic_splice_sendpage)
  /*
   * Attempt to initiate a splice from pipe to file.
   */
 -static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
 -                         loff_t *ppos, size_t len, unsigned int flags)
 +long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
 +                  loff_t *ppos, size_t len, unsigned int flags)
  {
        ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
                                loff_t *, size_t, unsigned int);
  
        return splice_write(pipe, out, ppos, len, flags);
  }
 +EXPORT_SYMBOL(do_splice_from);
  
  /*
   * Attempt to initiate a splice from a file to a pipe.
   */
 -static long do_splice_to(struct file *in, loff_t *ppos,
 -                       struct pipe_inode_info *pipe, size_t len,
 -                       unsigned int flags)
 +long do_splice_to(struct file *in, loff_t *ppos,
 +                struct pipe_inode_info *pipe, size_t len,
 +                unsigned int flags)
  {
        ssize_t (*splice_read)(struct file *, loff_t *,
                               struct pipe_inode_info *, size_t, unsigned int);
  
        return splice_read(in, ppos, pipe, len, flags);
  }
 +EXPORT_SYMBOL(do_splice_to);
  
  /**
   * splice_direct_to_actor - splices data directly between two non-pipes
diff --combined fs/ubifs/dir.c
@@@ -170,6 -170,8 +170,6 @@@ struct inode *ubifs_new_inode(struct ub
        return inode;
  }
  
 -#ifdef CONFIG_UBIFS_FS_DEBUG
 -
  static int dbg_check_name(const struct ubifs_info *c,
                          const struct ubifs_dent_node *dent,
                          const struct qstr *nm)
        return 0;
  }
  
 -#else
 -
 -#define dbg_check_name(c, dent, nm) 0
 -
 -#endif
 -
  static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry,
                                   struct nameidata *nd)
  {
@@@ -348,7 -356,7 +348,7 @@@ static unsigned int vfs_dent_type(uint8
   */
  static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
  {
-       int err, over = 0;
+       int err = 0, over = 0;
        loff_t pos = file->f_pos;
        struct qstr nm;
        union ubifs_key key;
        }
  
  out:
-       if (err != -ENOENT) {
+       if (err != -ENOENT)
                ubifs_err("cannot find next direntry, error %d", err);
-               return err;
-       }
+       else
+               /*
+                * -ENOENT is a non-fatal error in this context, the TNC uses
+                * it to indicate that the cursor moved past the current directory
+                * and readdir() has to stop.
+                */
+               err = 0;
  
        kfree(file->private_data);
        file->private_data = NULL;
        /* 2 is a special value indicating that there are no more direntries */
        file->f_pos = 2;
-       return 0;
+       return err;
  }
  
  static loff_t ubifs_dir_llseek(struct file *file, loff_t offset, int origin)
@@@ -582,7 -596,6 +588,7 @@@ static int ubifs_unlink(struct inode *d
        int sz_change = CALC_DENT_SIZE(dentry->d_name.len);
        int err, budgeted = 1;
        struct ubifs_budget_req req = { .mod_dent = 1, .dirtied_ino = 2 };
 +      unsigned int saved_nlink = inode->i_nlink;
  
        /*
         * Budget request settings: deletion direntry, deletion inode (+1 for
  out_cancel:
        dir->i_size += sz_change;
        dir_ui->ui_size = dir->i_size;
 -      inc_nlink(inode);
 +      set_nlink(inode, saved_nlink);
        unlock_2_inodes(dir, inode);
        if (budgeted)
                ubifs_release_budget(c, &req);
@@@ -721,7 -734,8 +727,7 @@@ out_cancel
        dir->i_size += sz_change;
        dir_ui->ui_size = dir->i_size;
        inc_nlink(dir);
 -      inc_nlink(inode);
 -      inc_nlink(inode);
 +      set_nlink(inode, 2);
        unlock_2_inodes(dir, inode);
        if (budgeted)
                ubifs_release_budget(c, &req);
@@@ -993,7 -1007,6 +999,7 @@@ static int ubifs_rename(struct inode *o
        struct ubifs_budget_req ino_req = { .dirtied_ino = 1,
                        .dirtied_ino_d = ALIGN(old_inode_ui->data_len, 8) };
        struct timespec time;
 +      unsigned int uninitialized_var(saved_nlink);
  
        /*
         * Budget request settings: deletion direntry, new direntry, removing
         * separately.
         */
  
 -      dbg_gen("dent '%.*s' ino %lu in dir ino %lu to dent '%.*s' in "
 -              "dir ino %lu", old_dentry->d_name.len, old_dentry->d_name.name,
 +      dbg_gen("dent '%.*s' ino %lu in dir ino %lu to dent '%.*s' in dir ino %lu",
 +              old_dentry->d_name.len, old_dentry->d_name.name,
                old_inode->i_ino, old_dir->i_ino, new_dentry->d_name.len,
                new_dentry->d_name.name, new_dir->i_ino);
        ubifs_assert(mutex_is_locked(&old_dir->i_mutex));
        if (unlink) {
                /*
                 * Directories cannot have hard-links, so if this is a
 -               * directory, decrement its @i_nlink twice because an empty
 -               * directory has @i_nlink 2.
 +               * directory, just clear @i_nlink.
                 */
 +              saved_nlink = new_inode->i_nlink;
                if (is_dir)
 +                      clear_nlink(new_inode);
 +              else
                        drop_nlink(new_inode);
                new_inode->i_ctime = time;
 -              drop_nlink(new_inode);
        } else {
                new_dir->i_size += new_sz;
                ubifs_inode(new_dir)->ui_size = new_dir->i_size;
  
  out_cancel:
        if (unlink) {
 -              if (is_dir)
 -                      inc_nlink(new_inode);
 -              inc_nlink(new_inode);
 +              set_nlink(new_inode, saved_nlink);
        } else {
                new_dir->i_size -= new_sz;
                ubifs_inode(new_dir)->ui_size = new_dir->i_size;
@@@ -1203,10 -1217,12 +1209,10 @@@ const struct inode_operations ubifs_dir
        .rename      = ubifs_rename,
        .setattr     = ubifs_setattr,
        .getattr     = ubifs_getattr,
 -#ifdef CONFIG_UBIFS_FS_XATTR
        .setxattr    = ubifs_setxattr,
        .getxattr    = ubifs_getxattr,
        .listxattr   = ubifs_listxattr,
        .removexattr = ubifs_removexattr,
 -#endif
  };
  
  const struct file_operations ubifs_dir_operations = {
diff --combined fs/ubifs/tnc.c
  #include <linux/slab.h>
  #include "ubifs.h"
  
+ static int try_read_node(const struct ubifs_info *c, void *buf, int type,
+                        int len, int lnum, int offs);
+ static int fallible_read_node(struct ubifs_info *c, const union ubifs_key *key,
+                             struct ubifs_zbranch *zbr, void *node);
  /*
   * Returned codes of 'matches_name()' and 'fallible_matches_name()' functions.
   * @NAME_LESS: name corresponding to the first argument is less than second
@@@ -339,16 -344,17 +344,16 @@@ static int lnc_add(struct ubifs_info *c
  
        err = ubifs_validate_entry(c, dent);
        if (err) {
 -              dbg_dump_stack();
 -              dbg_dump_node(c, dent);
 +              dump_stack();
 +              ubifs_dump_node(c, dent);
                return err;
        }
  
 -      lnc_node = kmalloc(zbr->len, GFP_NOFS);
 +      lnc_node = kmemdup(node, zbr->len, GFP_NOFS);
        if (!lnc_node)
                /* We don't have to have the cache, so no error */
                return 0;
  
 -      memcpy(lnc_node, node, zbr->len);
        zbr->leaf = lnc_node;
        return 0;
  }
@@@ -372,8 -378,8 +377,8 @@@ static int lnc_add_directly(struct ubif
  
        err = ubifs_validate_entry(c, node);
        if (err) {
 -              dbg_dump_stack();
 -              dbg_dump_node(c, node);
 +              dump_stack();
 +              ubifs_dump_node(c, node);
                return err;
        }
  
@@@ -419,7 -425,19 +424,19 @@@ static int tnc_read_node_nm(struct ubif
                return 0;
        }
  
-       err = ubifs_tnc_read_node(c, zbr, node);
+       if (c->replaying) {
+               err = fallible_read_node(c, &zbr->key, zbr, node);
+               /*
+                * When the node was not found, return -ENOENT, 0 otherwise.
+                * Negative return codes stay as-is.
+                */
+               if (err == 0)
+                       err = -ENOENT;
+               else if (err == 1)
+                       err = 0;
+       } else {
+               err = ubifs_tnc_read_node(c, zbr, node);
+       }
        if (err)
                return err;
  
@@@ -505,7 -523,7 +522,7 @@@ static int fallible_read_node(struct ub
  {
        int ret;
  
 -      dbg_tnc("LEB %d:%d, key %s", zbr->lnum, zbr->offs, DBGKEY(key));
 +      dbg_tnck(key, "LEB %d:%d, key ", zbr->lnum, zbr->offs);
  
        ret = try_read_node(c, node, key_type(c, key), zbr->len, zbr->lnum,
                            zbr->offs);
                        ret = 0;
        }
        if (ret == 0 && c->replaying)
 -              dbg_mnt("dangling branch LEB %d:%d len %d, key %s",
 -                      zbr->lnum, zbr->offs, zbr->len, DBGKEY(key));
 +              dbg_mntk(key, "dangling branch LEB %d:%d len %d, key ",
 +                      zbr->lnum, zbr->offs, zbr->len);
        return ret;
  }
  
@@@ -995,9 -1013,9 +1012,9 @@@ static int fallible_resolve_collision(s
        if (adding || !o_znode)
                return 0;
  
 -      dbg_mnt("dangling match LEB %d:%d len %d %s",
 +      dbg_mntk(key, "dangling match LEB %d:%d len %d key ",
                o_znode->zbranch[o_n].lnum, o_znode->zbranch[o_n].offs,
 -              o_znode->zbranch[o_n].len, DBGKEY(key));
 +              o_znode->zbranch[o_n].len);
        *zn = o_znode;
        *n = o_n;
        return 1;
@@@ -1179,7 -1197,7 +1196,7 @@@ int ubifs_lookup_level0(struct ubifs_in
        struct ubifs_znode *znode;
        unsigned long time = get_seconds();
  
 -      dbg_tnc("search key %s", DBGKEY(key));
 +      dbg_tnck(key, "search key ");
        ubifs_assert(key_type(c, key) < UBIFS_INVALID_KEY);
  
        znode = c->zroot.znode;
@@@ -1315,7 -1333,7 +1332,7 @@@ static int lookup_level0_dirty(struct u
        struct ubifs_znode *znode;
        unsigned long time = get_seconds();
  
 -      dbg_tnc("search and dirty key %s", DBGKEY(key));
 +      dbg_tnck(key, "search and dirty key ");
  
        znode = c->zroot.znode;
        if (unlikely(!znode)) {
@@@ -1722,8 -1740,8 +1739,8 @@@ static int validate_data_node(struct ub
        if (!keys_eq(c, &zbr->key, &key1)) {
                ubifs_err("bad key in node at LEB %d:%d",
                          zbr->lnum, zbr->offs);
 -              dbg_tnc("looked for key %s found node's key %s",
 -                      DBGKEY(&zbr->key), DBGKEY1(&key1));
 +              dbg_tnck(&zbr->key, "looked for key ");
 +              dbg_tnck(&key1, "found node's key ");
                goto out_err;
        }
  
@@@ -1733,8 -1751,8 +1750,8 @@@ out_err
        err = -EINVAL;
  out:
        ubifs_err("bad node at LEB %d:%d", zbr->lnum, zbr->offs);
 -      dbg_dump_node(c, buf);
 -      dbg_dump_stack();
 +      ubifs_dump_node(c, buf);
 +      dump_stack();
        return err;
  }
  
@@@ -1775,8 -1793,8 +1792,8 @@@ int ubifs_tnc_bulk_read(struct ubifs_in
        if (err && err != -EBADMSG) {
                ubifs_err("failed to read from LEB %d:%d, error %d",
                          lnum, offs, err);
 -              dbg_dump_stack();
 -              dbg_tnc("key %s", DBGKEY(&bu->key));
 +              dump_stack();
 +              dbg_tnck(&bu->key, "key ");
                return err;
        }
  
@@@ -1811,7 -1829,7 +1828,7 @@@ static int do_lookup_nm(struct ubifs_in
        int found, n, err;
        struct ubifs_znode *znode;
  
 -      dbg_tnc("name '%.*s' key %s", nm->len, nm->name, DBGKEY(key));
 +      dbg_tnck(key, "name '%.*s' key ", nm->len, nm->name);
        mutex_lock(&c->tnc_mutex);
        found = ubifs_lookup_level0(c, key, &znode, &n);
        if (!found) {
@@@ -1985,7 -2003,8 +2002,7 @@@ again
        zp = znode->parent;
        if (znode->child_cnt < c->fanout) {
                ubifs_assert(n != c->fanout);
 -              dbg_tnc("inserted at %d level %d, key %s", n, znode->level,
 -                      DBGKEY(key));
 +              dbg_tnck(key, "inserted at %d level %d, key ", n, znode->level);
  
                insert_zbranch(znode, zbr, n);
  
         * Unfortunately, @znode does not have more empty slots and we have to
         * split it.
         */
 -      dbg_tnc("splitting level %d, key %s", znode->level, DBGKEY(key));
 +      dbg_tnck(key, "splitting level %d, key ", znode->level);
  
        if (znode->alt)
                /*
@@@ -2094,7 -2113,7 +2111,7 @@@ do_split
        }
  
        /* Insert new key and branch */
 -      dbg_tnc("inserting at %d level %d, key %s", n, zn->level, DBGKEY(key));
 +      dbg_tnck(key, "inserting at %d level %d, key ", n, zn->level);
  
        insert_zbranch(zi, zbr, n);
  
@@@ -2170,7 -2189,7 +2187,7 @@@ int ubifs_tnc_add(struct ubifs_info *c
        struct ubifs_znode *znode;
  
        mutex_lock(&c->tnc_mutex);
 -      dbg_tnc("%d:%d, len %d, key %s", lnum, offs, len, DBGKEY(key));
 +      dbg_tnck(key, "%d:%d, len %d, key ", lnum, offs, len);
        found = lookup_level0_dirty(c, key, &znode, &n);
        if (!found) {
                struct ubifs_zbranch zbr;
@@@ -2219,8 -2238,8 +2236,8 @@@ int ubifs_tnc_replace(struct ubifs_inf
        struct ubifs_znode *znode;
  
        mutex_lock(&c->tnc_mutex);
 -      dbg_tnc("old LEB %d:%d, new LEB %d:%d, len %d, key %s", old_lnum,
 -              old_offs, lnum, offs, len, DBGKEY(key));
 +      dbg_tnck(key, "old LEB %d:%d, new LEB %d:%d, len %d, key ", old_lnum,
 +               old_offs, lnum, offs, len);
        found = lookup_level0_dirty(c, key, &znode, &n);
        if (found < 0) {
                err = found;
@@@ -2302,8 -2321,8 +2319,8 @@@ int ubifs_tnc_add_nm(struct ubifs_info 
        struct ubifs_znode *znode;
  
        mutex_lock(&c->tnc_mutex);
 -      dbg_tnc("LEB %d:%d, name '%.*s', key %s", lnum, offs, nm->len, nm->name,
 -              DBGKEY(key));
 +      dbg_tnck(key, "LEB %d:%d, name '%.*s', key ",
 +               lnum, offs, nm->len, nm->name);
        found = lookup_level0_dirty(c, key, &znode, &n);
        if (found < 0) {
                err = found;
@@@ -2396,14 -2415,14 +2413,14 @@@ static int tnc_delete(struct ubifs_inf
        /* Delete without merge for now */
        ubifs_assert(znode->level == 0);
        ubifs_assert(n >= 0 && n < c->fanout);
 -      dbg_tnc("deleting %s", DBGKEY(&znode->zbranch[n].key));
 +      dbg_tnck(&znode->zbranch[n].key, "deleting key ");
  
        zbr = &znode->zbranch[n];
        lnc_free(zbr);
  
        err = ubifs_add_dirt(c, zbr->lnum, zbr->len);
        if (err) {
 -              dbg_dump_znode(c, znode);
 +              ubifs_dump_znode(c, znode);
                return err;
        }
  
@@@ -2506,7 -2525,7 +2523,7 @@@ int ubifs_tnc_remove(struct ubifs_info 
        struct ubifs_znode *znode;
  
        mutex_lock(&c->tnc_mutex);
 -      dbg_tnc("key %s", DBGKEY(key));
 +      dbg_tnck(key, "key ");
        found = lookup_level0_dirty(c, key, &znode, &n);
        if (found < 0) {
                err = found;
@@@ -2537,7 -2556,7 +2554,7 @@@ int ubifs_tnc_remove_nm(struct ubifs_in
        struct ubifs_znode *znode;
  
        mutex_lock(&c->tnc_mutex);
 -      dbg_tnc("%.*s, key %s", nm->len, nm->name, DBGKEY(key));
 +      dbg_tnck(key, "%.*s, key ", nm->len, nm->name);
        err = lookup_level0_dirty(c, key, &znode, &n);
        if (err < 0)
                goto out_unlock;
@@@ -2649,10 -2668,10 +2666,10 @@@ int ubifs_tnc_remove_range(struct ubifs
                        err = ubifs_add_dirt(c, znode->zbranch[i].lnum,
                                             znode->zbranch[i].len);
                        if (err) {
 -                              dbg_dump_znode(c, znode);
 +                              ubifs_dump_znode(c, znode);
                                goto out_unlock;
                        }
 -                      dbg_tnc("removing %s", DBGKEY(key));
 +                      dbg_tnck(key, "removing key ");
                }
                if (k) {
                        for (i = n + 1 + k; i < znode->child_cnt; i++)
@@@ -2772,7 -2791,7 +2789,7 @@@ struct ubifs_dent_node *ubifs_tnc_next_
        struct ubifs_zbranch *zbr;
        union ubifs_key *dkey;
  
 -      dbg_tnc("%s %s", nm->name ? (char *)nm->name : "(lowest)", DBGKEY(key));
 +      dbg_tnck(key, "%s ", nm->name ? (char *)nm->name : "(lowest)");
        ubifs_assert(is_hash_key(c, key));
  
        mutex_lock(&c->tnc_mutex);
        if (nm->name) {
                if (err) {
                        /* Handle collisions */
-                       err = resolve_collision(c, key, &znode, &n, nm);
+                       if (c->replaying)
+                               err = fallible_resolve_collision(c, key, &znode, &n,
+                                                        nm, 0);
+                       else
+                               err = resolve_collision(c, key, &znode, &n, nm);
                        dbg_tnc("rc returned %d, znode %p, n %d",
                                err, znode, n);
                        if (unlikely(err < 0))
@@@ -3275,6 -3298,8 +3296,6 @@@ out_unlock
        return err;
  }
  
 -#ifdef CONFIG_UBIFS_FS_DEBUG
 -
  /**
   * dbg_check_inode_size - check if inode size is correct.
   * @c: UBIFS file-system description object
@@@ -3329,15 -3354,17 +3350,15 @@@ int dbg_check_inode_size(struct ubifs_i
  
  out_dump:
        block = key_block(c, key);
 -      ubifs_err("inode %lu has size %lld, but there are data at offset %lld "
 -                "(data key %s)", (unsigned long)inode->i_ino, size,
 -                ((loff_t)block) << UBIFS_BLOCK_SHIFT, DBGKEY(key));
 +      ubifs_err("inode %lu has size %lld, but there are data at offset %lld",
 +                (unsigned long)inode->i_ino, size,
 +                ((loff_t)block) << UBIFS_BLOCK_SHIFT);
        mutex_unlock(&c->tnc_mutex);
 -      dbg_dump_inode(c, inode);
 -      dbg_dump_stack();
 +      ubifs_dump_inode(c, inode);
 +      dump_stack();
        return -EINVAL;
  
  out_unlock:
        mutex_unlock(&c->tnc_mutex);
        return err;
  }
 -
 -#endif /* CONFIG_UBIFS_FS_DEBUG */
diff --combined fs/ubifs/xattr.c
@@@ -138,11 -138,12 +138,11 @@@ static int create_xattr(struct ubifs_in
        ui = ubifs_inode(inode);
        ui->xattr = 1;
        ui->flags |= UBIFS_XATTR_FL;
 -      ui->data = kmalloc(size, GFP_NOFS);
 +      ui->data = kmemdup(value, size, GFP_NOFS);
        if (!ui->data) {
                err = -ENOMEM;
                goto out_free;
        }
 -      memcpy(ui->data, value, size);
        inode->i_size = ui->ui_size = size;
        ui->data_len = size;
  
@@@ -167,6 -168,7 +167,7 @@@ out_cancel
        host_ui->xattr_cnt -= 1;
        host_ui->xattr_size -= CALC_DENT_SIZE(nm->len);
        host_ui->xattr_size -= CALC_XATTR_BYTES(size);
+       host_ui->xattr_names -= nm->len;
        mutex_unlock(&host_ui->ui_mutex);
  out_free:
        make_bad_inode(inode);
@@@ -203,11 -205,12 +204,11 @@@ static int change_xattr(struct ubifs_in
                return err;
  
        kfree(ui->data);
 -      ui->data = kmalloc(size, GFP_NOFS);
 +      ui->data = kmemdup(value, size, GFP_NOFS);
        if (!ui->data) {
                err = -ENOMEM;
                goto out_free;
        }
 -      memcpy(ui->data, value, size);
        inode->i_size = ui->ui_size = size;
        ui->data_len = size;
  
@@@ -399,8 -402,8 +400,8 @@@ ssize_t ubifs_getxattr(struct dentry *d
        if (buf) {
                /* If @buf is %NULL we are supposed to return the length */
                if (ui->data_len > size) {
 -                      dbg_err("buffer size %zd, xattr len %d",
 -                              size, ui->data_len);
 +                      ubifs_err("buffer size %zd, xattr len %d",
 +                                size, ui->data_len);
                        err = -ERANGE;
                        goto out_iput;
                }
@@@ -514,6 -517,7 +515,7 @@@ out_cancel
        host_ui->xattr_cnt += 1;
        host_ui->xattr_size += CALC_DENT_SIZE(nm->len);
        host_ui->xattr_size += CALC_XATTR_BYTES(ui->data_len);
+       host_ui->xattr_names += nm->len;
        mutex_unlock(&host_ui->ui_mutex);
        ubifs_release_budget(c, &req);
        make_bad_inode(inode);
diff --combined include/linux/mm.h
@@@ -1015,34 -1015,6 +1015,6 @@@ int set_page_dirty(struct page *page)
  int set_page_dirty_lock(struct page *page);
  int clear_page_dirty_for_io(struct page *page);
  
- /* Is the vma a continuation of the stack vma above it? */
- static inline int vma_growsdown(struct vm_area_struct *vma, unsigned long addr)
- {
-       return vma && (vma->vm_end == addr) && (vma->vm_flags & VM_GROWSDOWN);
- }
- static inline int stack_guard_page_start(struct vm_area_struct *vma,
-                                            unsigned long addr)
- {
-       return (vma->vm_flags & VM_GROWSDOWN) &&
-               (vma->vm_start == addr) &&
-               !vma_growsdown(vma->vm_prev, addr);
- }
- /* Is the vma a continuation of the stack vma below it? */
- static inline int vma_growsup(struct vm_area_struct *vma, unsigned long addr)
- {
-       return vma && (vma->vm_start == addr) && (vma->vm_flags & VM_GROWSUP);
- }
- static inline int stack_guard_page_end(struct vm_area_struct *vma,
-                                          unsigned long addr)
- {
-       return (vma->vm_flags & VM_GROWSUP) &&
-               (vma->vm_end == addr) &&
-               !vma_growsup(vma->vm_next, addr);
- }
  extern unsigned long move_page_tables(struct vm_area_struct *vma,
                unsigned long old_addr, struct vm_area_struct *new_vma,
                unsigned long new_addr, unsigned long len);
@@@ -1462,6 -1434,7 +1434,7 @@@ unsigned long ra_submit(struct file_ra_
                        struct address_space *mapping,
                        struct file *filp);
  
+ extern unsigned long stack_guard_gap;
  /* Generic expand stack which grows the stack according to GROWS{UP,DOWN} */
  extern int expand_stack(struct vm_area_struct *vma, unsigned long address);
  
@@@ -1490,6 -1463,30 +1463,30 @@@ static inline struct vm_area_struct * f
        return vma;
  }
  
+ static inline unsigned long vm_start_gap(struct vm_area_struct *vma)
+ {
+       unsigned long vm_start = vma->vm_start;
+       if (vma->vm_flags & VM_GROWSDOWN) {
+               vm_start -= stack_guard_gap;
+               if (vm_start > vma->vm_start)
+                       vm_start = 0;
+       }
+       return vm_start;
+ }
+ static inline unsigned long vm_end_gap(struct vm_area_struct *vma)
+ {
+       unsigned long vm_end = vma->vm_end;
+       if (vma->vm_flags & VM_GROWSUP) {
+               vm_end += stack_guard_gap;
+               if (vm_end < vma->vm_end)
+                       vm_end = -PAGE_SIZE;
+       }
+       return vm_end;
+ }
  static inline unsigned long vma_pages(struct vm_area_struct *vma)
  {
        return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
@@@ -1634,22 -1631,5 +1631,22 @@@ extern void copy_user_huge_page(struct 
                                unsigned int pages_per_huge_page);
  #endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLBFS */
  
 +#ifdef CONFIG_DEBUG_PAGEALLOC
 +extern unsigned int _debug_guardpage_minorder;
 +
 +static inline unsigned int debug_guardpage_minorder(void)
 +{
 +      return _debug_guardpage_minorder;
 +}
 +
 +static inline bool page_is_guard(struct page *page)
 +{
 +      return test_bit(PAGE_DEBUG_FLAG_GUARD, &page->debug_flags);
 +}
 +#else
 +static inline unsigned int debug_guardpage_minorder(void) { return 0; }
 +static inline bool page_is_guard(struct page *page) { return false; }
 +#endif /* CONFIG_DEBUG_PAGEALLOC */
 +
  #endif /* __KERNEL__ */
  #endif /* _LINUX_MM_H */
diff --combined kernel/sched.c
@@@ -3617,8 -3617,9 +3617,9 @@@ void calc_load_exit_idle(void
        struct rq *this_rq = this_rq();
  
        /*
-        * If we're still before the sample window, we're done.
+        * If we're still before the pending sample window, we're done.
         */
+       this_rq->calc_load_update = calc_load_update;
        if (time_before(jiffies, this_rq->calc_load_update))
                return;
  
         * accounted through the nohz accounting, so skip the entire deal and
         * sync up for the next window.
         */
-       this_rq->calc_load_update = calc_load_update;
        if (time_before(jiffies, this_rq->calc_load_update + 10))
                this_rq->calc_load_update += LOAD_FREQ;
  }
@@@ -5329,7 -5329,6 +5329,7 @@@ int can_nice(const struct task_struct *
        return (nice_rlim <= task_rlimit(p, RLIMIT_NICE) ||
                capable(CAP_SYS_NICE));
  }
 +EXPORT_SYMBOL_GPL(can_nice);
  
  #ifdef __ARCH_WANT_SYS_NICE
  
@@@ -8527,7 -8526,6 +8527,7 @@@ void __init sched_init(void
  #ifdef CONFIG_CGROUP_SCHED
        list_add(&root_task_group.list, &task_groups);
        INIT_LIST_HEAD(&root_task_group.children);
 +      INIT_LIST_HEAD(&root_task_group.siblings);
        autogroup_init(&init_task);
  #endif /* CONFIG_CGROUP_SCHED */
  
diff --combined kernel/trace/trace.c
@@@ -1100,7 -1100,7 +1100,7 @@@ void trace_find_cmdline(int pid, char c
        arch_spin_lock(&trace_cmdline_lock);
        map = map_pid_to_cmdline[pid];
        if (map != NO_CMDLINE_MAP)
-               strcpy(comm, saved_cmdlines[map]);
+               strlcpy(comm, saved_cmdlines[map], TASK_COMM_LEN);
        else
                strcpy(comm, "<...>");
  
@@@ -4440,7 -4440,7 +4440,7 @@@ static const struct file_operations tra
  };
  
  struct dentry *trace_create_file(const char *name,
 -                               mode_t mode,
 +                               umode_t mode,
                                 struct dentry *parent,
                                 void *data,
                                 const struct file_operations *fops)
diff --combined mm/huge_memory.c
@@@ -65,17 -65,6 +65,17 @@@ static void khugepaged_slab_free(void)
  static struct hlist_head *mm_slots_hash __read_mostly;
  static struct kmem_cache *mm_slot_cache __read_mostly;
  
 +#ifdef CONFIG_FB
 +extern const struct file_operations fb_fops;
 +
 +#define is_fb_vma(vma) \
 +      (vma->vm_file && vma->vm_file->f_op == &fb_fops)
 +#else
 +#define is_fb_vma(vma) 0
 +#endif
 +
 +static void split_fb_pmd(struct vm_area_struct *vma, pmd_t *pmd);
 +
  /**
   * struct mm_slot - hash lookup from mm to mm_slot
   * @hash: hash collision list
@@@ -549,7 -538,7 +549,7 @@@ static int __init hugepage_init(void
         * where the extra memory used could hurt more than TLB overhead
         * is likely to save.  The admin can still enable it through /sys.
         */
 -      if (totalram_pages < (512 << (20 - PAGE_SHIFT)))
 +      if (totalram_pages < (200 << (20 - PAGE_SHIFT)))
                transparent_hugepage_flags = 0;
  
        start_khugepaged();
@@@ -801,28 -790,6 +801,28 @@@ pgtable_t get_pmd_huge_pte(struct mm_st
        return pgtable;
  }
  
 +void huge_pmd_set_accessed(struct mm_struct *mm,
 +                         struct vm_area_struct *vma,
 +                         unsigned long address,
 +                         pmd_t *pmd, pmd_t orig_pmd,
 +                         int dirty)
 +{
 +      pmd_t entry;
 +      unsigned long haddr;
 +
 +      spin_lock(&mm->page_table_lock);
 +      if (unlikely(!pmd_same(*pmd, orig_pmd)))
 +              goto unlock;
 +
 +      entry = pmd_mkyoung(orig_pmd);
 +      haddr = address & HPAGE_PMD_MASK;
 +      if (pmdp_set_access_flags(vma, haddr, pmd, entry, dirty))
 +              update_mmu_cache_pmd(vma, address, pmd);
 +
 +unlock:
 +      spin_unlock(&mm->page_table_lock);
 +}
 +
  static int do_huge_pmd_wp_page_fallback(struct mm_struct *mm,
                                        struct vm_area_struct *vma,
                                        unsigned long address,
@@@ -936,7 -903,7 +936,7 @@@ int do_huge_pmd_wp_page(struct mm_struc
                entry = pmd_mkyoung(orig_pmd);
                entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma);
                if (pmdp_set_access_flags(vma, haddr, pmd, entry,  1))
 -                      update_mmu_cache(vma, address, entry);
 +                      update_mmu_cache(vma, address, pmd);
                ret |= VM_FAULT_WRITE;
                goto out_unlock;
        }
                pmdp_clear_flush_notify(vma, haddr, pmd);
                page_add_new_anon_rmap(new_page, vma, haddr);
                set_pmd_at(mm, haddr, pmd, entry);
 -              update_mmu_cache(vma, address, entry);
 +              update_mmu_cache(vma, address, pmd);
                page_remove_rmap(page);
                put_page(page);
                ret |= VM_FAULT_WRITE;
@@@ -997,6 -964,18 +997,18 @@@ out
        return ret;
  }
  
+ /*
+  * FOLL_FORCE can write to even unwritable pmd's, but only
+  * after we've gone through a COW cycle and they are dirty.
+  */
+ static inline bool can_follow_write_pmd(pmd_t pmd, struct page *page,
+                                       unsigned int flags)
+ {
+       return pmd_write(pmd) ||
+               ((flags & FOLL_FORCE) && (flags & FOLL_COW) &&
+                page && PageAnon(page));
+ }
  struct page *follow_trans_huge_pmd(struct mm_struct *mm,
                                   unsigned long addr,
                                   pmd_t *pmd,
  
        assert_spin_locked(&mm->page_table_lock);
  
-       if (flags & FOLL_WRITE && !pmd_write(*pmd))
-               goto out;
        page = pmd_page(*pmd);
        VM_BUG_ON(!PageHead(page));
+       if (flags & FOLL_WRITE && !can_follow_write_pmd(*pmd, page, flags))
+               return NULL;
        if (flags & FOLL_TOUCH) {
                pmd_t _pmd;
                /*
@@@ -1040,11 -1020,6 +1053,11 @@@ int zap_huge_pmd(struct mmu_gather *tlb
  
        spin_lock(&tlb->mm->page_table_lock);
        if (likely(pmd_trans_huge(*pmd))) {
 +              if (is_fb_vma(vma)) {
 +                      split_fb_pmd(vma, pmd);
 +                      return 0;
 +              }
 +
                if (unlikely(pmd_trans_splitting(*pmd))) {
                        spin_unlock(&tlb->mm->page_table_lock);
                        wait_split_huge_page(vma->anon_vma,
        return ret;
  }
  
 +/* callers must hold mmap_sem (madvise() does) */
 +static int collapse_fb_pmd(struct mm_struct *mm, pmd_t *pmd,
 +      unsigned long addr, struct vm_area_struct *vma)
 +{
 +      unsigned long _addr;
 +      struct page *page;
 +      pgtable_t pgtable;
 +      pte_t *pte, *_pte;
 +      pmd_t _pmd;
 +      u32 pa;
 +
 +      pte = pte_offset_map(pmd, addr);
 +      page = pte_page(*pte);
 +      pa = __pfn_to_phys(page_to_pfn(page));
 +      _pmd = pmdp_clear_flush_notify(vma, addr, pmd);
 +
 +      if ((addr | pa) & ~HPAGE_PMD_MASK) {
 +              printk(KERN_ERR "collapse_fb: bad alignment: %08lx->%08x\n",
 +                      addr, pa);
 +              pte_unmap(pte);
 +              return -EINVAL;
 +      }
 +
 +      for (_pte = pte, _addr = addr; _pte < pte + HPAGE_PMD_NR; _pte++) {
 +              pte_t pteval = *_pte;
 +              struct page *src_page;
 +
 +              if (!pte_none(pteval)) {
 +                      src_page = pte_page(pteval);
 +
 +                      pte_clear(vma->vm_mm, _addr, _pte);
 +                      if (pte_present(pteval))
 +                              page_remove_rmap(src_page);
 +              }
 +
 +              _addr += PAGE_SIZE;
 +      }
 +
 +      pte_unmap(pte);
 +      pgtable = pmd_pgtable(_pmd);
 +      VM_BUG_ON(page_count(pgtable) != 1);
 +      VM_BUG_ON(page_mapcount(pgtable) != 0);
 +
 +      _pmd = mk_pmd(page, vma->vm_page_prot);
 +      _pmd = maybe_pmd_mkwrite(pmd_mkdirty(_pmd), vma);
 +      _pmd = pmd_mkhuge(_pmd);
 +
 +      smp_wmb();
 +
 +      spin_lock(&mm->page_table_lock);
 +      BUG_ON(!pmd_none(*pmd));
 +      set_pmd_at(mm, addr, pmd, _pmd);
 +      update_mmu_cache(vma, addr, pmd);
 +      prepare_pmd_huge_pte(pgtable, mm);
 +      spin_unlock(&mm->page_table_lock);
 +
 +      return 0;
 +}
 +
 +static int try_collapse_fb(struct vm_area_struct *vma)
 +{
 +      struct mm_struct *mm = vma->vm_mm;
 +      unsigned long hstart, hend, addr;
 +      int ret = 0;
 +      pgd_t *pgd;
 +      pud_t *pud;
 +      pmd_t *pmd;
 +
 +      hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK;
 +      hend = vma->vm_end & HPAGE_PMD_MASK;
 +      if (hstart >= hend)
 +              return -EINVAL;
 +
 +      for (addr = hstart; addr < hend; addr += HPAGE_PMD_SIZE) {
 +              pgd = pgd_offset(mm, addr);
 +              if (!pgd_present(*pgd))
 +                      return -EINVAL;
 +
 +              pud = pud_offset(pgd, addr);
 +              if (!pud_present(*pud))
 +                      return -EINVAL;
 +
 +              pmd = pmd_offset(pud, addr);
 +              if (!pmd_present(*pmd))
 +                      return -EINVAL;
 +              if (pmd_trans_huge(*pmd))
 +                      continue;
 +
 +              ret = collapse_fb_pmd(mm, pmd, addr, vma);
 +              if (ret)
 +                      break;
 +      }
 +
 +      return ret;
 +}
 +
 +/* undo collapse_fb_pmd(), restore pages so that mm subsys can release them
 + * page_table_lock() should be held */
 +static void split_fb_pmd(struct vm_area_struct *vma, pmd_t *pmd)
 +{
 +      struct mm_struct *mm = vma->vm_mm;
 +      unsigned long addr, haddr, pfn;
 +      struct page *page;
 +      pgtable_t pgtable;
 +      pmd_t _pmd;
 +      int i;
 +
 +      page = pmd_page(*pmd);
 +      pgtable = get_pmd_huge_pte(mm);
 +      pfn = page_to_pfn(page);
 +      addr = pfn << PAGE_SHIFT;
 +
 +      pmd_populate(mm, &_pmd, pgtable);
 +
 +      for (i = 0, haddr = addr; i < HPAGE_PMD_NR; i++, haddr += PAGE_SIZE) {
 +              pte_t *pte, entry;
 +              BUG_ON(PageCompound(page + i));
 +              entry = mk_pte(page + i, vma->vm_page_prot);
 +              entry = maybe_mkwrite(pte_mkdirty(entry), vma);
 +              if (!pmd_young(*pmd))
 +                      entry = pte_mkold(entry);
 +              atomic_set(&page[i]._mapcount, 0); // hack?
 +              pte = pte_offset_map(&_pmd, haddr);
 +              BUG_ON(!pte_none(*pte));
 +              set_pte_at(mm, haddr, pte, entry);
 +              pte_unmap(pte);
 +      }
 +
 +      set_pmd_at(mm, addr, pmd, pmd_mknotpresent(*pmd));
 +      flush_tlb_range(vma, addr, addr + HPAGE_PMD_SIZE);
 +      pmd_populate(mm, pmd, pgtable);
 +}
 +
 +#ifndef __arm__
 +#error arm only..
 +#endif
 +static u32 pmd_to_va(struct mm_struct *mm, pmd_t *pmd)
 +{
 +      pgd_t *pgd;
 +      pud_t *pud;
 +      pmd_t *pmd0;
 +      u32 ret;
 +
 +      pgd = pgd_offset(mm, 0);
 +      pud = pud_offset(pgd, 0);
 +      pmd0 = pmd_offset(pud, 0);
 +
 +      ret = (pmd - pmd0) << SECTION_SHIFT;
 +      return ret;
 +}
 +
  #define VM_NO_THP (VM_SPECIAL|VM_INSERTPAGE|VM_MIXEDMAP|VM_SAO| \
                   VM_HUGETLB|VM_SHARED|VM_MAYSHARE)
  
@@@ -1670,9 -1494,6 +1683,9 @@@ int hugepage_madvise(struct vm_area_str
  {
        switch (advice) {
        case MADV_HUGEPAGE:
 +              if (is_fb_vma(vma))
 +                      return try_collapse_fb(vma);
 +
                /*
                 * Be somewhat over-protective like KSM for now!
                 */
@@@ -2176,7 -1997,7 +2189,7 @@@ static void collapse_huge_page(struct m
        BUG_ON(!pmd_none(*pmd));
        page_add_new_anon_rmap(new_page, vma, address);
        set_pmd_at(mm, address, pmd, _pmd);
 -      update_mmu_cache(vma, address, _pmd);
 +      update_mmu_cache(vma, address, pmd);
        prepare_pmd_huge_pte(pgtable, mm);
        spin_unlock(&mm->page_table_lock);
  
@@@ -2551,7 -2372,6 +2564,7 @@@ static int khugepaged(void *none
  
  void __split_huge_page_pmd(struct mm_struct *mm, pmd_t *pmd)
  {
 +      struct vm_area_struct *vma;
        struct page *page;
  
        spin_lock(&mm->page_table_lock);
                spin_unlock(&mm->page_table_lock);
                return;
        }
 +      vma = find_vma(mm, pmd_to_va(mm, pmd));
 +      if (vma && is_fb_vma(vma)) {
 +              split_fb_pmd(vma, pmd);
 +              spin_unlock(&mm->page_table_lock);
 +              return;
 +      }
        page = pmd_page(*pmd);
        VM_BUG_ON(!page_count(page));
        get_page(page);
diff --combined mm/memory.c
@@@ -1403,7 -1403,6 +1403,7 @@@ unsigned long zap_page_range(struct vm_
        tlb_finish_mmu(&tlb, address, end);
        return end;
  }
 +EXPORT_SYMBOL_GPL(zap_page_range);
  
  /**
   * zap_vma_ptes - remove ptes mapping the vma
@@@ -1606,12 -1605,6 +1606,6 @@@ no_page_table
        return page;
  }
  
- static inline int stack_guard_page(struct vm_area_struct *vma, unsigned long addr)
- {
-       return stack_guard_page_start(vma, addr) ||
-              stack_guard_page_end(vma, addr+PAGE_SIZE);
- }
  /**
   * __get_user_pages() - pin user pages in memory
   * @tsk:      task_struct of target task
@@@ -1762,11 -1755,6 +1756,6 @@@ int __get_user_pages(struct task_struc
                                int ret;
                                unsigned int fault_flags = 0;
  
-                               /* For mlock, just skip the stack guard page. */
-                               if (foll_flags & FOLL_MLOCK) {
-                                       if (stack_guard_page(vma, start))
-                                               goto next_page;
-                               }
                                if (foll_flags & FOLL_WRITE)
                                        fault_flags |= FAULT_FLAG_WRITE;
                                if (nonblocking)
@@@ -3122,40 -3110,6 +3111,6 @@@ out_release
        return ret;
  }
  
- /*
-  * This is like a special single-page "expand_{down|up}wards()",
-  * except we must first make sure that 'address{-|+}PAGE_SIZE'
-  * doesn't hit another vma.
-  */
- static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned long address)
- {
-       address &= PAGE_MASK;
-       if ((vma->vm_flags & VM_GROWSDOWN) && address == vma->vm_start) {
-               struct vm_area_struct *prev = vma->vm_prev;
-               /*
-                * Is there a mapping abutting this one below?
-                *
-                * That's only ok if it's the same stack mapping
-                * that has gotten split..
-                */
-               if (prev && prev->vm_end == address)
-                       return prev->vm_flags & VM_GROWSDOWN ? 0 : -ENOMEM;
-               return expand_downwards(vma, address - PAGE_SIZE);
-       }
-       if ((vma->vm_flags & VM_GROWSUP) && address + PAGE_SIZE == vma->vm_end) {
-               struct vm_area_struct *next = vma->vm_next;
-               /* As VM_GROWSDOWN but s/below/above/ */
-               if (next && next->vm_start == address + PAGE_SIZE)
-                       return next->vm_flags & VM_GROWSUP ? 0 : -ENOMEM;
-               return expand_upwards(vma, address + PAGE_SIZE);
-       }
-       return 0;
- }
  /*
   * We enter with non-exclusive mmap_sem (to exclude vma changes,
   * but allow concurrent faults), and pte mapped but not yet locked.
@@@ -3175,10 -3129,6 +3130,6 @@@ static int do_anonymous_page(struct mm_
        if (vma->vm_flags & VM_SHARED)
                return VM_FAULT_SIGBUS;
  
-       /* Check if we need to add a guard page to the stack */
-       if (check_stack_guard_page(vma, address) < 0)
-               return VM_FAULT_SIGSEGV;
        /* Use the zero-page for reads */
        if (!(flags & FAULT_FLAG_WRITE)) {
                entry = pte_mkspecial(pfn_pte(my_zero_pfn(address),
@@@ -3576,9 -3526,8 +3527,9 @@@ retry
  
                barrier();
                if (pmd_trans_huge(orig_pmd)) {
 -                      if (flags & FAULT_FLAG_WRITE &&
 -                          !pmd_write(orig_pmd) &&
 +                      unsigned int dirty = flags & FAULT_FLAG_WRITE;
 +
 +                      if (dirty && !pmd_write(orig_pmd) &&
                            !pmd_trans_splitting(orig_pmd)) {
                                ret = do_huge_pmd_wp_page(mm, vma, address, pmd,
                                                          orig_pmd);
                                if (unlikely(ret & VM_FAULT_OOM))
                                        goto retry;
                                return ret;
 +                      } else {
 +                              huge_pmd_set_accessed(mm, vma, address, pmd,
 +                                                    orig_pmd, dirty);
                        }
                        return 0;
                }
@@@ -3907,11 -3853,7 +3858,11 @@@ static int __access_remote_vm(struct ta
                        vma = find_vma(mm, addr);
                        if (!vma || vma->vm_start > addr)
                                break;
 -                      if (vma->vm_ops && vma->vm_ops->access)
 +                      if ((vma->vm_flags & VM_PFNMAP) &&
 +                          !(vma->vm_flags & VM_IO))
 +                              ret = generic_access_phys(vma, addr, buf,
 +                                                        len, write);
 +                      if (ret <= 0 && vma->vm_ops && vma->vm_ops->access)
                                ret = vma->vm_ops->access(vma, addr, buf,
                                                          len, write);
                        if (ret <= 0)
diff --combined mm/swapfile.c
@@@ -667,10 -667,10 +667,10 @@@ int try_to_free_swap(struct page *page
         * original page might be freed under memory pressure, then
         * later read back in from swap, now with the wrong data.
         *
 -       * Hibernation clears bits from gfp_allowed_mask to prevent
 -       * memory reclaim from writing to disk, so check that here.
 +       * Hibration suspends storage while it is writing the image
 +       * to disk so check that here.
         */
 -      if (!(gfp_allowed_mask & __GFP_IO))
 +      if (pm_suspended_storage())
                return 0;
  
        delete_from_swap_cache(page);
@@@ -1913,6 -1913,8 +1913,8 @@@ static unsigned long read_swap_header(s
                swab32s(&swap_header->info.version);
                swab32s(&swap_header->info.last_page);
                swab32s(&swap_header->info.nr_badpages);
+               if (swap_header->info.nr_badpages > MAX_SWAP_BADPAGES)
+                       return 0;
                for (i = 0; i < swap_header->info.nr_badpages; i++)
                        swab32s(&swap_header->info.badpages[i]);
        }