diff options
| -rw-r--r-- | arch/ia64/kernel/ptrace.c | 6 | ||||
| -rw-r--r-- | arch/ia64/kernel/traps.c | 11 | ||||
| -rw-r--r-- | include/asm-ia64/processor.h | 10 |
3 files changed, 24 insertions, 3 deletions
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index 08c8a5eb25ab..575a8f657b31 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c | |||
| @@ -635,11 +635,17 @@ ia64_flush_fph (struct task_struct *task) | |||
| 635 | { | 635 | { |
| 636 | struct ia64_psr *psr = ia64_psr(ia64_task_regs(task)); | 636 | struct ia64_psr *psr = ia64_psr(ia64_task_regs(task)); |
| 637 | 637 | ||
| 638 | /* | ||
| 639 | * Prevent migrating this task while | ||
| 640 | * we're fiddling with the FPU state | ||
| 641 | */ | ||
| 642 | preempt_disable(); | ||
| 638 | if (ia64_is_local_fpu_owner(task) && psr->mfh) { | 643 | if (ia64_is_local_fpu_owner(task) && psr->mfh) { |
| 639 | psr->mfh = 0; | 644 | psr->mfh = 0; |
| 640 | task->thread.flags |= IA64_THREAD_FPH_VALID; | 645 | task->thread.flags |= IA64_THREAD_FPH_VALID; |
| 641 | ia64_save_fpu(&task->thread.fph[0]); | 646 | ia64_save_fpu(&task->thread.fph[0]); |
| 642 | } | 647 | } |
| 648 | preempt_enable(); | ||
| 643 | } | 649 | } |
| 644 | 650 | ||
| 645 | /* | 651 | /* |
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index 9bad6652d531..1861173bd4f6 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c | |||
| @@ -220,13 +220,21 @@ disabled_fph_fault (struct pt_regs *regs) | |||
| 220 | 220 | ||
| 221 | /* first, grant user-level access to fph partition: */ | 221 | /* first, grant user-level access to fph partition: */ |
| 222 | psr->dfh = 0; | 222 | psr->dfh = 0; |
| 223 | |||
| 224 | /* | ||
| 225 | * Make sure that no other task gets in on this processor | ||
| 226 | * while we're claiming the FPU | ||
| 227 | */ | ||
| 228 | preempt_disable(); | ||
| 223 | #ifndef CONFIG_SMP | 229 | #ifndef CONFIG_SMP |
| 224 | { | 230 | { |
| 225 | struct task_struct *fpu_owner | 231 | struct task_struct *fpu_owner |
| 226 | = (struct task_struct *)ia64_get_kr(IA64_KR_FPU_OWNER); | 232 | = (struct task_struct *)ia64_get_kr(IA64_KR_FPU_OWNER); |
| 227 | 233 | ||
| 228 | if (ia64_is_local_fpu_owner(current)) | 234 | if (ia64_is_local_fpu_owner(current)) { |
| 235 | preempt_enable_no_resched(); | ||
| 229 | return; | 236 | return; |
| 237 | } | ||
| 230 | 238 | ||
| 231 | if (fpu_owner) | 239 | if (fpu_owner) |
| 232 | ia64_flush_fph(fpu_owner); | 240 | ia64_flush_fph(fpu_owner); |
| @@ -244,6 +252,7 @@ disabled_fph_fault (struct pt_regs *regs) | |||
| 244 | */ | 252 | */ |
| 245 | psr->mfh = 1; | 253 | psr->mfh = 1; |
| 246 | } | 254 | } |
| 255 | preempt_enable_no_resched(); | ||
| 247 | } | 256 | } |
| 248 | 257 | ||
| 249 | static inline int | 258 | static inline int |
diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h index 9e1ba8b7fb68..91bbd1f22461 100644 --- a/include/asm-ia64/processor.h +++ b/include/asm-ia64/processor.h | |||
| @@ -403,7 +403,10 @@ extern void ia64_setreg_unknown_kr (void); | |||
| 403 | * task_struct at this point. | 403 | * task_struct at this point. |
| 404 | */ | 404 | */ |
| 405 | 405 | ||
| 406 | /* Return TRUE if task T owns the fph partition of the CPU we're running on. */ | 406 | /* |
| 407 | * Return TRUE if task T owns the fph partition of the CPU we're running on. | ||
| 408 | * Must be called from code that has preemption disabled. | ||
| 409 | */ | ||
| 407 | #define ia64_is_local_fpu_owner(t) \ | 410 | #define ia64_is_local_fpu_owner(t) \ |
| 408 | ({ \ | 411 | ({ \ |
| 409 | struct task_struct *__ia64_islfo_task = (t); \ | 412 | struct task_struct *__ia64_islfo_task = (t); \ |
| @@ -411,7 +414,10 @@ extern void ia64_setreg_unknown_kr (void); | |||
| 411 | && __ia64_islfo_task == (struct task_struct *) ia64_get_kr(IA64_KR_FPU_OWNER)); \ | 414 | && __ia64_islfo_task == (struct task_struct *) ia64_get_kr(IA64_KR_FPU_OWNER)); \ |
| 412 | }) | 415 | }) |
| 413 | 416 | ||
| 414 | /* Mark task T as owning the fph partition of the CPU we're running on. */ | 417 | /* |
| 418 | * Mark task T as owning the fph partition of the CPU we're running on. | ||
| 419 | * Must be called from code that has preemption disabled. | ||
| 420 | */ | ||
| 415 | #define ia64_set_local_fpu_owner(t) do { \ | 421 | #define ia64_set_local_fpu_owner(t) do { \ |
| 416 | struct task_struct *__ia64_slfo_task = (t); \ | 422 | struct task_struct *__ia64_slfo_task = (t); \ |
| 417 | __ia64_slfo_task->thread.last_fph_cpu = smp_processor_id(); \ | 423 | __ia64_slfo_task->thread.last_fph_cpu = smp_processor_id(); \ |
