userfaultfd: hugetlbfs: add copy_huge_page_from_user for hugetlb userfaultfd support
[linux-2.6-microblaze.git] / include / linux / mm.h
index a92c8d7..6bc7f2c 100644 (file)
@@ -76,6 +76,10 @@ extern int mmap_rnd_compat_bits __read_mostly;
 #define page_to_virt(x)        __va(PFN_PHYS(page_to_pfn(x)))
 #endif
 
+#ifndef lm_alias
+#define lm_alias(x)    __va(__pa_symbol(x))
+#endif
+
 /*
  * To prevent common memory management code establishing
  * a zero page mapping on a read fault.
@@ -281,6 +285,17 @@ extern pgprot_t protection_map[16];
 #define FAULT_FLAG_REMOTE      0x80    /* faulting for non current tsk/mm */
 #define FAULT_FLAG_INSTRUCTION  0x100  /* The fault was during an instruction fetch */
 
+#define FAULT_FLAG_TRACE \
+       { FAULT_FLAG_WRITE,             "WRITE" }, \
+       { FAULT_FLAG_MKWRITE,           "MKWRITE" }, \
+       { FAULT_FLAG_ALLOW_RETRY,       "ALLOW_RETRY" }, \
+       { FAULT_FLAG_RETRY_NOWAIT,      "RETRY_NOWAIT" }, \
+       { FAULT_FLAG_KILLABLE,          "KILLABLE" }, \
+       { FAULT_FLAG_TRIED,             "TRIED" }, \
+       { FAULT_FLAG_USER,              "USER" }, \
+       { FAULT_FLAG_REMOTE,            "REMOTE" }, \
+       { FAULT_FLAG_INSTRUCTION,       "INSTRUCTION" }
+
 /*
  * vm_fault is filled by the the pagefault handler and passed to the vma's
  * ->fault function. The vma's ->fault is responsible for returning a bitmask
@@ -292,36 +307,23 @@ extern pgprot_t protection_map[16];
  * pgoff should be used in favour of virtual_address, if possible.
  */
 struct vm_fault {
+       struct vm_area_struct *vma;     /* Target VMA */
        unsigned int flags;             /* FAULT_FLAG_xxx flags */
        gfp_t gfp_mask;                 /* gfp mask to be used for allocations */
        pgoff_t pgoff;                  /* Logical page offset based on vma */
-       void __user *virtual_address;   /* Faulting virtual address */
+       unsigned long address;          /* Faulting virtual address */
+       pmd_t *pmd;                     /* Pointer to pmd entry matching
+                                        * the 'address' */
+       pte_t orig_pte;                 /* Value of PTE at the time of fault */
 
-       struct page *cow_page;          /* Handler may choose to COW */
+       struct page *cow_page;          /* Page handler may use for COW fault */
+       struct mem_cgroup *memcg;       /* Cgroup cow_page belongs to */
        struct page *page;              /* ->fault handlers should return a
                                         * page here, unless VM_FAULT_NOPAGE
                                         * is set (which is also implied by
                                         * VM_FAULT_ERROR).
                                         */
-       void *entry;                    /* ->fault handler can alternatively
-                                        * return locked DAX entry. In that
-                                        * case handler should return
-                                        * VM_FAULT_DAX_LOCKED and fill in
-                                        * entry here.
-                                        */
-};
-
-/*
- * Page fault context: passes though page fault handler instead of endless list
- * of function arguments.
- */
-struct fault_env {
-       struct vm_area_struct *vma;     /* Target VMA */
-       unsigned long address;          /* Faulting virtual address */
-       unsigned int flags;             /* FAULT_FLAG_xxx flags */
-       pmd_t *pmd;                     /* Pointer to pmd entry matching
-                                        * the 'address'
-                                        */
+       /* These three entries are valid only while holding ptl lock */
        pte_t *pte;                     /* Pointer to pte entry matching
                                         * the 'address'. NULL if the page
                                         * table hasn't been allocated.
@@ -349,9 +351,8 @@ struct vm_operations_struct {
        void (*close)(struct vm_area_struct * area);
        int (*mremap)(struct vm_area_struct * area);
        int (*fault)(struct vm_area_struct *vma, struct vm_fault *vmf);
-       int (*pmd_fault)(struct vm_area_struct *, unsigned long address,
-                                               pmd_t *, unsigned int flags);
-       void (*map_pages)(struct fault_env *fe,
+       int (*pmd_fault)(struct vm_fault *vmf);
+       void (*map_pages)(struct vm_fault *vmf,
                        pgoff_t start_pgoff, pgoff_t end_pgoff);
 
        /* notification that a previously read-only page is about to become
@@ -625,8 +626,10 @@ static inline pte_t maybe_mkwrite(pte_t pte, struct vm_area_struct *vma)
        return pte;
 }
 
-int alloc_set_pte(struct fault_env *fe, struct mem_cgroup *memcg,
+int alloc_set_pte(struct vm_fault *vmf, struct mem_cgroup *memcg,
                struct page *page);
+int finish_fault(struct vm_fault *vmf);
+int finish_mkwrite_fault(struct vm_fault *vmf);
 #endif
 
 /*
@@ -1110,7 +1113,7 @@ static inline void clear_page_pfmemalloc(struct page *page)
 #define VM_FAULT_LOCKED        0x0200  /* ->fault locked the returned page */
 #define VM_FAULT_RETRY 0x0400  /* ->fault blocked, must retry */
 #define VM_FAULT_FALLBACK 0x0800       /* huge page fault failed, fall back to small */
-#define VM_FAULT_DAX_LOCKED 0x1000     /* ->fault has locked DAX entry */
+#define VM_FAULT_DONE_COW   0x1000     /* ->fault has fully handled COW */
 
 #define VM_FAULT_HWPOISON_LARGE_MASK 0xf000 /* encodes hpage index for large hwpoison */
 
@@ -1118,6 +1121,20 @@ static inline void clear_page_pfmemalloc(struct page *page)
                         VM_FAULT_HWPOISON | VM_FAULT_HWPOISON_LARGE | \
                         VM_FAULT_FALLBACK)
 
+#define VM_FAULT_RESULT_TRACE \
+       { VM_FAULT_OOM,                 "OOM" }, \
+       { VM_FAULT_SIGBUS,              "SIGBUS" }, \
+       { VM_FAULT_MAJOR,               "MAJOR" }, \
+       { VM_FAULT_WRITE,               "WRITE" }, \
+       { VM_FAULT_HWPOISON,            "HWPOISON" }, \
+       { VM_FAULT_HWPOISON_LARGE,      "HWPOISON_LARGE" }, \
+       { VM_FAULT_SIGSEGV,             "SIGSEGV" }, \
+       { VM_FAULT_NOPAGE,              "NOPAGE" }, \
+       { VM_FAULT_LOCKED,              "LOCKED" }, \
+       { VM_FAULT_RETRY,               "RETRY" }, \
+       { VM_FAULT_FALLBACK,            "FALLBACK" }, \
+       { VM_FAULT_DONE_COW,            "DONE_COW" }
+
 /* Encode hstate index for a hwpoisoned large page */
 #define VM_FAULT_SET_HINDEX(x) ((x) << 12)
 #define VM_FAULT_GET_HINDEX(x) (((x) >> 12) & 0xf)
@@ -1221,6 +1238,8 @@ int copy_page_range(struct mm_struct *dst, struct mm_struct *src,
                        struct vm_area_struct *vma);
 void unmap_mapping_range(struct address_space *mapping,
                loff_t const holebegin, loff_t const holelen, int even_cows);
+int follow_pte_pmd(struct mm_struct *mm, unsigned long address,
+                            pte_t **ptepp, pmd_t **pmdpp, spinlock_t **ptlp);
 int follow_pfn(struct vm_area_struct *vma, unsigned long address,
        unsigned long *pfn);
 int follow_phys(struct vm_area_struct *vma, unsigned long address,
@@ -1270,19 +1289,18 @@ extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *
                unsigned int gup_flags);
 extern int access_remote_vm(struct mm_struct *mm, unsigned long addr,
                void *buf, int len, unsigned int gup_flags);
+extern int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
+               unsigned long addr, void *buf, int len, unsigned int gup_flags);
 
 long get_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm,
                            unsigned long start, unsigned long nr_pages,
                            unsigned int gup_flags, struct page **pages,
-                           struct vm_area_struct **vmas);
+                           struct vm_area_struct **vmas, int *locked);
 long get_user_pages(unsigned long start, unsigned long nr_pages,
                            unsigned int gup_flags, struct page **pages,
                            struct vm_area_struct **vmas);
 long get_user_pages_locked(unsigned long start, unsigned long nr_pages,
                    unsigned int gup_flags, struct page **pages, int *locked);
-long __get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm,
-                              unsigned long start, unsigned long nr_pages,
-                              struct page **pages, unsigned int gup_flags);
 long get_user_pages_unlocked(unsigned long start, unsigned long nr_pages,
                    struct page **pages, unsigned int gup_flags);
 int get_user_pages_fast(unsigned long start, int nr_pages, int write,
@@ -1768,6 +1786,8 @@ static inline spinlock_t *pmd_lock(struct mm_struct *mm, pmd_t *pmd)
        return ptl;
 }
 
+extern void __init pagecache_init(void);
+
 extern void free_area_init(unsigned long * zones_size);
 extern void free_area_init_node(int nid, unsigned long * zones_size,
                unsigned long zone_start_pfn, unsigned long *zholes_size);
@@ -2097,7 +2117,7 @@ extern void truncate_inode_pages_final(struct address_space *);
 
 /* generic vm_area_ops exported for stackable file systems */
 extern int filemap_fault(struct vm_area_struct *, struct vm_fault *);
-extern void filemap_map_pages(struct fault_env *fe,
+extern void filemap_map_pages(struct vm_fault *vmf,
                pgoff_t start_pgoff, pgoff_t end_pgoff);
 extern int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf);
 
@@ -2404,6 +2424,9 @@ extern void clear_huge_page(struct page *page,
 extern void copy_user_huge_page(struct page *dst, struct page *src,
                                unsigned long addr, struct vm_area_struct *vma,
                                unsigned int pages_per_huge_page);
+extern long copy_huge_page_from_user(struct page *dst_page,
+                               const void __user *usr_src,
+                               unsigned int pages_per_huge_page);
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLBFS */
 
 extern struct page_ext_operations debug_guardpage_ops;