diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2013-11-13 23:01:43 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2013-11-20 18:33:37 -0500 |
commit | 95f715b08fa4a953771398d20cbe35a6803ea41d (patch) | |
tree | 6ccc7e13cb8a501232b3d5b153222fe5cb3c4b7b /arch | |
parent | 0b5381a61821d1c074c76e01b27bf5f69cf2dd01 (diff) |
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>
Diffstat (limited to 'arch')
-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 6936547018b8..c5f734e20b0f 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, | |||
123 | struct mm_struct *mm = current->mm; | 123 | struct mm_struct *mm = current->mm; |
124 | unsigned long addr, len, end; | 124 | unsigned long addr, len, end; |
125 | unsigned long next; | 125 | unsigned long next; |
126 | unsigned long flags; | ||
126 | pgd_t *pgdp; | 127 | pgd_t *pgdp; |
127 | int nr = 0; | 128 | int nr = 0; |
128 | 129 | ||
@@ -156,7 +157,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write, | |||
156 | * So long as we atomically load page table pointers versus teardown, | 157 | * So long as we atomically load page table pointers versus teardown, |
157 | * we can follow the address down to the the page and take a ref on it. | 158 | * we can follow the address down to the the page and take a ref on it. |
158 | */ | 159 | */ |
159 | local_irq_disable(); | 160 | local_irq_save(flags); |
160 | 161 | ||
161 | pgdp = pgd_offset(mm, addr); | 162 | pgdp = pgd_offset(mm, addr); |
162 | do { | 163 | do { |
@@ -179,7 +180,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write, | |||
179 | break; | 180 | break; |
180 | } while (pgdp++, addr = next, addr != end); | 181 | } while (pgdp++, addr = next, addr != end); |
181 | 182 | ||
182 | local_irq_enable(); | 183 | local_irq_restore(flags); |
183 | 184 | ||
184 | return nr; | 185 | return nr; |
185 | } | 186 | } |