]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - mm/memory.c
ARM: dts: imx6ul: add support for Ka-Ro electronics TXUL mainboard
[karo-tx-linux.git] / mm / memory.c
index 635451abc8f7c9b84663535678a26a9b0848c89d..d279350424fa8876785e780d2d30904e7cd88bb4 100644 (file)
@@ -1105,6 +1105,12 @@ again:
 
                        if (!PageAnon(page)) {
                                if (pte_dirty(ptent)) {
+                                       /*
+                                        * oom_reaper cannot tear down dirty
+                                        * pages
+                                        */
+                                       if (unlikely(details && details->ignore_dirty))
+                                               continue;
                                        force_flush = 1;
                                        set_page_dirty(page);
                                }
@@ -1123,8 +1129,8 @@ again:
                        }
                        continue;
                }
-               /* If details->check_mapping, we leave swap entries. */
-               if (unlikely(details))
+               /* only check swap_entries if explicitly asked for in details */
+               if (unlikely(details && !details->check_swap_entries))
                        continue;
 
                entry = pte_to_swp_entry(ptent);
@@ -1229,7 +1235,7 @@ static inline unsigned long zap_pud_range(struct mmu_gather *tlb,
        return addr;
 }
 
-static void unmap_page_range(struct mmu_gather *tlb,
+void unmap_page_range(struct mmu_gather *tlb,
                             struct vm_area_struct *vma,
                             unsigned long addr, unsigned long end,
                             struct zap_details *details)
@@ -1237,9 +1243,6 @@ static void unmap_page_range(struct mmu_gather *tlb,
        pgd_t *pgd;
        unsigned long next;
 
-       if (details && !details->check_mapping)
-               details = NULL;
-
        BUG_ON(addr >= end);
        tlb_start_vma(tlb, vma);
        pgd = pgd_offset(vma->vm_mm, addr);
@@ -1550,9 +1553,30 @@ out:
  */
 int vm_insert_pfn(struct vm_area_struct *vma, unsigned long addr,
                        unsigned long pfn)
+{
+       return vm_insert_pfn_prot(vma, addr, pfn, vma->vm_page_prot);
+}
+EXPORT_SYMBOL(vm_insert_pfn);
+
+/**
+ * vm_insert_pfn_prot - insert single pfn into user vma with specified pgprot
+ * @vma: user vma to map to
+ * @addr: target user address of this page
+ * @pfn: source kernel pfn
+ * @pgprot: pgprot flags for the inserted page
+ *
+ * This is exactly like vm_insert_pfn, except that it allows drivers to
+ * to override pgprot on a per-page basis.
+ *
+ * This only makes sense for IO mappings, and it makes no sense for
+ * cow mappings.  In general, using multiple vmas is preferable;
+ * vm_insert_pfn_prot should only be used if using multiple VMAs is
+ * impractical.
+ */
+int vm_insert_pfn_prot(struct vm_area_struct *vma, unsigned long addr,
+                       unsigned long pfn, pgprot_t pgprot)
 {
        int ret;
-       pgprot_t pgprot = vma->vm_page_prot;
        /*
         * Technically, architectures with pte_special can avoid all these
         * restrictions (same for remap_pfn_range).  However we would like
@@ -1574,7 +1598,7 @@ int vm_insert_pfn(struct vm_area_struct *vma, unsigned long addr,
 
        return ret;
 }
-EXPORT_SYMBOL(vm_insert_pfn);
+EXPORT_SYMBOL(vm_insert_pfn_prot);
 
 int vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr,
                        pfn_t pfn)
@@ -1876,7 +1900,9 @@ int apply_to_page_range(struct mm_struct *mm, unsigned long addr,
        unsigned long end = addr + size;
        int err;
 
-       BUG_ON(addr >= end);
+       if (WARN_ON(addr >= end))
+               return -EINVAL;
+
        pgd = pgd_offset(mm, addr);
        do {
                next = pgd_addr_end(addr, end);
@@ -2412,7 +2438,7 @@ static inline void unmap_mapping_range_tree(struct rb_root *root,
 void unmap_mapping_range(struct address_space *mapping,
                loff_t const holebegin, loff_t const holelen, int even_cows)
 {
-       struct zap_details details;
+       struct zap_details details = { };
        pgoff_t hba = holebegin >> PAGE_SHIFT;
        pgoff_t hlen = (holelen + PAGE_SIZE - 1) >> PAGE_SHIFT;
 
@@ -2447,7 +2473,7 @@ EXPORT_SYMBOL(unmap_mapping_range);
  * We return with the mmap_sem locked or unlocked in the same cases
  * as does filemap_fault().
  */
-static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
+int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
                unsigned long address, pte_t *page_table, pmd_t *pmd,
                unsigned int flags, pte_t orig_pte)
 {
@@ -3122,8 +3148,7 @@ static int do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
                unsigned long address, pte_t *page_table, pmd_t *pmd,
                unsigned int flags, pte_t orig_pte)
 {
-       pgoff_t pgoff = (((address & PAGE_MASK)
-                       - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
+       pgoff_t pgoff = linear_page_index(vma, address);
 
        pte_unmap(page_table);
        /* The VMA was not fully populated on mmap() or missing VM_DONTEXPAND */