diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-02-06 06:36:23 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-02-15 16:39:53 -0500 |
commit | ad187f956108e1c56b444706212bf08d84c0bee0 (patch) | |
tree | 5aa54adb07016a87be9629aea20a6fd363d449c2 /arch/arm/vfp/vfpmodule.c | |
parent | 54cb3dbb4a1cccd6b1bffc169ff638f8e74daf44 (diff) |
ARM: vfp ptrace: no point flushing hw context for PTRACE_GETVFPREGS
If we're only reading the VFP context via the ptrace call, there's
no need to invalidate the hardware context - we only need to do that
on PTRACE_SETVFPREGS. This allows more efficient monitoring of a
traced task.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/vfp/vfpmodule.c')
-rw-r--r-- | arch/arm/vfp/vfpmodule.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 86a57aeeda4a..def19f83d812 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c | |||
@@ -430,7 +430,11 @@ static inline void vfp_pm_init(void) { } | |||
430 | * saved one. This function is used by the ptrace mechanism. | 430 | * saved one. This function is used by the ptrace mechanism. |
431 | */ | 431 | */ |
432 | #ifdef CONFIG_SMP | 432 | #ifdef CONFIG_SMP |
433 | void vfp_sync_state(struct thread_info *thread) | 433 | void vfp_sync_hwstate(struct thread_info *thread) |
434 | { | ||
435 | } | ||
436 | |||
437 | void vfp_flush_hwstate(struct thread_info *thread) | ||
434 | { | 438 | { |
435 | /* | 439 | /* |
436 | * On SMP systems, the VFP state is automatically saved at every | 440 | * On SMP systems, the VFP state is automatically saved at every |
@@ -441,7 +445,7 @@ void vfp_sync_state(struct thread_info *thread) | |||
441 | thread->vfpstate.hard.cpu = NR_CPUS; | 445 | thread->vfpstate.hard.cpu = NR_CPUS; |
442 | } | 446 | } |
443 | #else | 447 | #else |
444 | void vfp_sync_state(struct thread_info *thread) | 448 | void vfp_sync_hwstate(struct thread_info *thread) |
445 | { | 449 | { |
446 | unsigned int cpu = get_cpu(); | 450 | unsigned int cpu = get_cpu(); |
447 | 451 | ||
@@ -457,6 +461,23 @@ void vfp_sync_state(struct thread_info *thread) | |||
457 | */ | 461 | */ |
458 | fmxr(FPEXC, fpexc | FPEXC_EN); | 462 | fmxr(FPEXC, fpexc | FPEXC_EN); |
459 | vfp_save_state(&thread->vfpstate, fpexc | FPEXC_EN); | 463 | vfp_save_state(&thread->vfpstate, fpexc | FPEXC_EN); |
464 | fmxr(FPEXC, fpexc); | ||
465 | } | ||
466 | |||
467 | put_cpu(); | ||
468 | } | ||
469 | |||
470 | void vfp_flush_hwstate(struct thread_info *thread) | ||
471 | { | ||
472 | unsigned int cpu = get_cpu(); | ||
473 | |||
474 | /* | ||
475 | * If the thread we're interested in is the current owner of the | ||
476 | * hardware VFP state, then we need to save its state. | ||
477 | */ | ||
478 | if (last_VFP_context[cpu] == &thread->vfpstate) { | ||
479 | u32 fpexc = fmrx(FPEXC); | ||
480 | |||
460 | fmxr(FPEXC, fpexc & ~FPEXC_EN); | 481 | fmxr(FPEXC, fpexc & ~FPEXC_EN); |
461 | 482 | ||
462 | /* | 483 | /* |