diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2013-11-14 04:01:43 (GMT) |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2013-11-20 23:33:37 (GMT) |
commit | 95f715b08fa4a953771398d20cbe35a6803ea41d (patch) | |
tree | 6ccc7e13cb8a501232b3d5b153222fe5cb3c4b7b | |
parent | 0b5381a61821d1c074c76e01b27bf5f69cf2dd01 (diff) | |
download | linux-95f715b08fa4a953771398d20cbe35a6803ea41d.tar.xz |
powerpc: Fix __get_user_pages_fast() irq handling
__get_user_pages_fast() may be called with interrupts disabled (see e.g.
get_futex_key() in kernel/futex.c) and therefore should use local_irq_save()
and local_irq_restore() instead of local_irq_disable()/enable().
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
CC: <stable@vger.kernel.org> [v3.12]
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r-- | arch/powerpc/mm/gup.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/arch/powerpc/mm/gup.c b/arch/powerpc/mm/gup.c index 6936547..c5f734e 100644 --- a/arch/powerpc/mm/gup.c +++ b/arch/powerpc/mm/gup.c @@ -123,6 +123,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write, struct mm_struct *mm = current->mm; unsigned long addr, len, end; unsigned long next; + unsigned long flags; pgd_t *pgdp; int nr = 0; @@ -156,7 +157,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write, * So long as we atomically load page table pointers versus teardown, * we can follow the address down to the the page and take a ref on it. */ - local_irq_disable(); + local_irq_save(flags); pgdp = pgd_offset(mm, addr); do { @@ -179,7 +180,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write, break; } while (pgdp++, addr = next, addr != end); - local_irq_enable(); + local_irq_restore(flags); return nr; } |