diff options
Diffstat (limited to 'mm/nommu.c')
-rw-r--r-- | mm/nommu.c | 44 |
1 files changed, 33 insertions, 11 deletions
diff --git a/mm/nommu.c b/mm/nommu.c index ed75bc962fb..2696b24f2bb 100644 --- a/mm/nommu.c +++ b/mm/nommu.c | |||
@@ -34,6 +34,8 @@ | |||
34 | #include <asm/tlb.h> | 34 | #include <asm/tlb.h> |
35 | #include <asm/tlbflush.h> | 35 | #include <asm/tlbflush.h> |
36 | 36 | ||
37 | #include "internal.h" | ||
38 | |||
37 | void *high_memory; | 39 | void *high_memory; |
38 | struct page *mem_map; | 40 | struct page *mem_map; |
39 | unsigned long max_mapnr; | 41 | unsigned long max_mapnr; |
@@ -128,20 +130,16 @@ unsigned int kobjsize(const void *objp) | |||
128 | return PAGE_SIZE << compound_order(page); | 130 | return PAGE_SIZE << compound_order(page); |
129 | } | 131 | } |
130 | 132 | ||
131 | /* | 133 | int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, |
132 | * get a list of pages in an address range belonging to the specified process | 134 | unsigned long start, int len, int flags, |
133 | * and indicate the VMA that covers each page | 135 | struct page **pages, struct vm_area_struct **vmas) |
134 | * - this is potentially dodgy as we may end incrementing the page count of a | ||
135 | * slab page or a secondary page from a compound page | ||
136 | * - don't permit access to VMAs that don't support it, such as I/O mappings | ||
137 | */ | ||
138 | int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | ||
139 | unsigned long start, int len, int write, int force, | ||
140 | struct page **pages, struct vm_area_struct **vmas) | ||
141 | { | 136 | { |
142 | struct vm_area_struct *vma; | 137 | struct vm_area_struct *vma; |
143 | unsigned long vm_flags; | 138 | unsigned long vm_flags; |
144 | int i; | 139 | int i; |
140 | int write = !!(flags & GUP_FLAGS_WRITE); | ||
141 | int force = !!(flags & GUP_FLAGS_FORCE); | ||
142 | int ignore = !!(flags & GUP_FLAGS_IGNORE_VMA_PERMISSIONS); | ||
145 | 143 | ||
146 | /* calculate required read or write permissions. | 144 | /* calculate required read or write permissions. |
147 | * - if 'force' is set, we only require the "MAY" flags. | 145 | * - if 'force' is set, we only require the "MAY" flags. |
@@ -156,7 +154,7 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | |||
156 | 154 | ||
157 | /* protect what we can, including chardevs */ | 155 | /* protect what we can, including chardevs */ |
158 | if (vma->vm_flags & (VM_IO | VM_PFNMAP) || | 156 | if (vma->vm_flags & (VM_IO | VM_PFNMAP) || |
159 | !(vm_flags & vma->vm_flags)) | 157 | (!ignore && !(vm_flags & vma->vm_flags))) |
160 | goto finish_or_fault; | 158 | goto finish_or_fault; |
161 | 159 | ||
162 | if (pages) { | 160 | if (pages) { |
@@ -174,6 +172,30 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | |||
174 | finish_or_fault: | 172 | finish_or_fault: |
175 | return i ? : -EFAULT; | 173 | return i ? : -EFAULT; |
176 | } | 174 | } |
175 | |||
176 | |||
177 | /* | ||
178 | * get a list of pages in an address range belonging to the specified process | ||
179 | * and indicate the VMA that covers each page | ||
180 | * - this is potentially dodgy as we may end incrementing the page count of a | ||
181 | * slab page or a secondary page from a compound page | ||
182 | * - don't permit access to VMAs that don't support it, such as I/O mappings | ||
183 | */ | ||
184 | int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | ||
185 | unsigned long start, int len, int write, int force, | ||
186 | struct page **pages, struct vm_area_struct **vmas) | ||
187 | { | ||
188 | int flags = 0; | ||
189 | |||
190 | if (write) | ||
191 | flags |= GUP_FLAGS_WRITE; | ||
192 | if (force) | ||
193 | flags |= GUP_FLAGS_FORCE; | ||
194 | |||
195 | return __get_user_pages(tsk, mm, | ||
196 | start, len, flags, | ||
197 | pages, vmas); | ||
198 | } | ||
177 | EXPORT_SYMBOL(get_user_pages); | 199 | EXPORT_SYMBOL(get_user_pages); |
178 | 200 | ||
179 | DEFINE_RWLOCK(vmlist_lock); | 201 | DEFINE_RWLOCK(vmlist_lock); |