From 58415357f8f9c04fc13a4a78462a800cddf4af41 Mon Sep 17 00:00:00 2001 From: Gerald Schaefer Date: Tue, 4 Sep 2012 15:37:55 +0200 Subject: [PATCH] --- yaml --- r: 324084 b: refs/heads/master c: 34cda99260247873df53ae00885fb0f426b149a5 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/s390/mm/gup.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 9de7cf8998d8..16f3fb33e6ab 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 25502f0015a8d6dd4bb34336ddb3eac6b1a55317 +refs/heads/master: 34cda99260247873df53ae00885fb0f426b149a5 diff --git a/trunk/arch/s390/mm/gup.c b/trunk/arch/s390/mm/gup.c index 65cb06e2af4e..eeaf8023851f 100644 --- a/trunk/arch/s390/mm/gup.c +++ b/trunk/arch/s390/mm/gup.c @@ -154,6 +154,43 @@ static inline int gup_pud_range(pgd_t *pgdp, pgd_t pgd, unsigned long addr, return 1; } +/* + * Like get_user_pages_fast() except its IRQ-safe in that it won't fall + * back to the regular GUP. + */ +int __get_user_pages_fast(unsigned long start, int nr_pages, int write, + struct page **pages) +{ + struct mm_struct *mm = current->mm; + unsigned long addr, len, end; + unsigned long next, flags; + pgd_t *pgdp, pgd; + int nr = 0; + + start &= PAGE_MASK; + addr = start; + len = (unsigned long) nr_pages << PAGE_SHIFT; + end = start + len; + if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ, + (void __user *)start, len))) + return 0; + + local_irq_save(flags); + pgdp = pgd_offset(mm, addr); + do { + pgd = *pgdp; + barrier(); + next = pgd_addr_end(addr, end); + if (pgd_none(pgd)) + break; + if (!gup_pud_range(pgdp, pgd, addr, next, write, pages, &nr)) + break; + } while (pgdp++, addr = next, addr != end); + local_irq_restore(flags); + + return nr; +} + /** * get_user_pages_fast() - pin user pages in memory * @start: starting user address