diff options
author | Gerald Schaefer <gerald.schaefer@de.ibm.com> | 2012-09-04 09:37:55 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2012-09-26 09:45:08 -0400 |
commit | 34cda99260247873df53ae00885fb0f426b149a5 (patch) | |
tree | af5b82520a729e3c68493b247ebb99a7ae65ca1a /arch/s390/mm | |
parent | 25502f0015a8d6dd4bb34336ddb3eac6b1a55317 (diff) |
s390/mm: implement __get_user_pages_fast()
This patch introduces the __get_user_pages_fast() function on s390,
which will be needed with CONFIG_TRANSPARENT_HUGEPAGE and futex.
Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/mm')
-rw-r--r-- | arch/s390/mm/gup.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c index 65cb06e2af4e..eeaf8023851f 100644 --- a/arch/s390/mm/gup.c +++ b/arch/s390/mm/gup.c | |||
@@ -154,6 +154,43 @@ static inline int gup_pud_range(pgd_t *pgdp, pgd_t pgd, unsigned long addr, | |||
154 | return 1; | 154 | return 1; |
155 | } | 155 | } |
156 | 156 | ||
157 | /* | ||
158 | * Like get_user_pages_fast() except its IRQ-safe in that it won't fall | ||
159 | * back to the regular GUP. | ||
160 | */ | ||
161 | int __get_user_pages_fast(unsigned long start, int nr_pages, int write, | ||
162 | struct page **pages) | ||
163 | { | ||
164 | struct mm_struct *mm = current->mm; | ||
165 | unsigned long addr, len, end; | ||
166 | unsigned long next, flags; | ||
167 | pgd_t *pgdp, pgd; | ||
168 | int nr = 0; | ||
169 | |||
170 | start &= PAGE_MASK; | ||
171 | addr = start; | ||
172 | len = (unsigned long) nr_pages << PAGE_SHIFT; | ||
173 | end = start + len; | ||
174 | if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ, | ||
175 | (void __user *)start, len))) | ||
176 | return 0; | ||
177 | |||
178 | local_irq_save(flags); | ||
179 | pgdp = pgd_offset(mm, addr); | ||
180 | do { | ||
181 | pgd = *pgdp; | ||
182 | barrier(); | ||
183 | next = pgd_addr_end(addr, end); | ||
184 | if (pgd_none(pgd)) | ||
185 | break; | ||
186 | if (!gup_pud_range(pgdp, pgd, addr, next, write, pages, &nr)) | ||
187 | break; | ||
188 | } while (pgdp++, addr = next, addr != end); | ||
189 | local_irq_restore(flags); | ||
190 | |||
191 | return nr; | ||
192 | } | ||
193 | |||
157 | /** | 194 | /** |
158 | * get_user_pages_fast() - pin user pages in memory | 195 | * get_user_pages_fast() - pin user pages in memory |
159 | * @start: starting user address | 196 | * @start: starting user address |