aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc64/kernel/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ppc64/kernel/process.c')
-rw-r--r--arch/ppc64/kernel/process.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c
index 7a7e027653ad..887005358eb1 100644
--- a/arch/ppc64/kernel/process.c
+++ b/arch/ppc64/kernel/process.c
@@ -54,6 +54,7 @@
54#include <asm/sections.h> 54#include <asm/sections.h>
55#include <asm/tlbflush.h> 55#include <asm/tlbflush.h>
56#include <asm/time.h> 56#include <asm/time.h>
57#include <asm/plpar_wrappers.h>
57 58
58#ifndef CONFIG_SMP 59#ifndef CONFIG_SMP
59struct task_struct *last_task_used_math = NULL; 60struct task_struct *last_task_used_math = NULL;
@@ -163,7 +164,30 @@ int dump_task_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)
163 164
164#endif /* CONFIG_ALTIVEC */ 165#endif /* CONFIG_ALTIVEC */
165 166
167static void set_dabr_spr(unsigned long val)
168{
169 mtspr(SPRN_DABR, val);
170}
171
172int set_dabr(unsigned long dabr)
173{
174 int ret = 0;
175
176 if (firmware_has_feature(FW_FEATURE_XDABR)) {
177 /* We want to catch accesses from kernel and userspace */
178 unsigned long flags = H_DABRX_KERNEL|H_DABRX_USER;
179 ret = plpar_set_xdabr(dabr, flags);
180 } else if (firmware_has_feature(FW_FEATURE_DABR)) {
181 ret = plpar_set_dabr(dabr);
182 } else {
183 set_dabr_spr(dabr);
184 }
185
186 return ret;
187}
188
166DEFINE_PER_CPU(struct cpu_usage, cpu_usage_array); 189DEFINE_PER_CPU(struct cpu_usage, cpu_usage_array);
190static DEFINE_PER_CPU(unsigned long, current_dabr);
167 191
168struct task_struct *__switch_to(struct task_struct *prev, 192struct task_struct *__switch_to(struct task_struct *prev,
169 struct task_struct *new) 193 struct task_struct *new)
@@ -198,6 +222,11 @@ struct task_struct *__switch_to(struct task_struct *prev,
198 new->thread.regs->msr |= MSR_VEC; 222 new->thread.regs->msr |= MSR_VEC;
199#endif /* CONFIG_ALTIVEC */ 223#endif /* CONFIG_ALTIVEC */
200 224
225 if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr)) {
226 set_dabr(new->thread.dabr);
227 __get_cpu_var(current_dabr) = new->thread.dabr;
228 }
229
201 flush_tlb_pending(); 230 flush_tlb_pending();
202 231
203 new_thread = &new->thread; 232 new_thread = &new->thread;
@@ -334,6 +363,11 @@ void flush_thread(void)
334 last_task_used_altivec = NULL; 363 last_task_used_altivec = NULL;
335#endif /* CONFIG_ALTIVEC */ 364#endif /* CONFIG_ALTIVEC */
336#endif /* CONFIG_SMP */ 365#endif /* CONFIG_SMP */
366
367 if (current->thread.dabr) {
368 current->thread.dabr = 0;
369 set_dabr(0);
370 }
337} 371}
338 372
339void 373void