diff options
Diffstat (limited to 'arch/powerpc/mm/stab.c')
| -rw-r--r-- | arch/powerpc/mm/stab.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/arch/powerpc/mm/stab.c b/arch/powerpc/mm/stab.c index 98cd1dc2ae75..ab5fb48b3e90 100644 --- a/arch/powerpc/mm/stab.c +++ b/arch/powerpc/mm/stab.c | |||
| @@ -164,7 +164,7 @@ void switch_stab(struct task_struct *tsk, struct mm_struct *mm) | |||
| 164 | { | 164 | { |
| 165 | struct stab_entry *stab = (struct stab_entry *) get_paca()->stab_addr; | 165 | struct stab_entry *stab = (struct stab_entry *) get_paca()->stab_addr; |
| 166 | struct stab_entry *ste; | 166 | struct stab_entry *ste; |
| 167 | unsigned long offset = __get_cpu_var(stab_cache_ptr); | 167 | unsigned long offset; |
| 168 | unsigned long pc = KSTK_EIP(tsk); | 168 | unsigned long pc = KSTK_EIP(tsk); |
| 169 | unsigned long stack = KSTK_ESP(tsk); | 169 | unsigned long stack = KSTK_ESP(tsk); |
| 170 | unsigned long unmapped_base; | 170 | unsigned long unmapped_base; |
| @@ -172,6 +172,15 @@ void switch_stab(struct task_struct *tsk, struct mm_struct *mm) | |||
| 172 | /* Force previous translations to complete. DRENG */ | 172 | /* Force previous translations to complete. DRENG */ |
| 173 | asm volatile("isync" : : : "memory"); | 173 | asm volatile("isync" : : : "memory"); |
| 174 | 174 | ||
| 175 | /* | ||
| 176 | * We need interrupts hard-disabled here, not just soft-disabled, | ||
| 177 | * so that a PMU interrupt can't occur, which might try to access | ||
| 178 | * user memory (to get a stack trace) and possible cause an STAB miss | ||
| 179 | * which would update the stab_cache/stab_cache_ptr per-cpu variables. | ||
| 180 | */ | ||
| 181 | hard_irq_disable(); | ||
| 182 | |||
| 183 | offset = __get_cpu_var(stab_cache_ptr); | ||
| 175 | if (offset <= NR_STAB_CACHE_ENTRIES) { | 184 | if (offset <= NR_STAB_CACHE_ENTRIES) { |
| 176 | int i; | 185 | int i; |
| 177 | 186 | ||
