diff options
-rw-r--r-- | arch/arm/vfp/vfpmodule.c | 36 |
1 files changed, 16 insertions, 20 deletions
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index f60a5400a25b..86a57aeeda4a 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c | |||
@@ -444,32 +444,28 @@ void vfp_sync_state(struct thread_info *thread) | |||
444 | void vfp_sync_state(struct thread_info *thread) | 444 | void vfp_sync_state(struct thread_info *thread) |
445 | { | 445 | { |
446 | unsigned int cpu = get_cpu(); | 446 | unsigned int cpu = get_cpu(); |
447 | u32 fpexc = fmrx(FPEXC); | ||
448 | 447 | ||
449 | /* | 448 | /* |
450 | * If VFP is enabled, the previous state was already saved and | 449 | * If the thread we're interested in is the current owner of the |
451 | * last_VFP_context updated. | 450 | * hardware VFP state, then we need to save its state. |
452 | */ | 451 | */ |
453 | if (fpexc & FPEXC_EN) | 452 | if (last_VFP_context[cpu] == &thread->vfpstate) { |
454 | goto out; | 453 | u32 fpexc = fmrx(FPEXC); |
455 | |||
456 | if (!last_VFP_context[cpu]) | ||
457 | goto out; | ||
458 | 454 | ||
459 | /* | 455 | /* |
460 | * Save the last VFP state on this CPU. | 456 | * Save the last VFP state on this CPU. |
461 | */ | 457 | */ |
462 | fmxr(FPEXC, fpexc | FPEXC_EN); | 458 | fmxr(FPEXC, fpexc | FPEXC_EN); |
463 | vfp_save_state(last_VFP_context[cpu], fpexc); | 459 | vfp_save_state(&thread->vfpstate, fpexc | FPEXC_EN); |
464 | fmxr(FPEXC, fpexc); | 460 | fmxr(FPEXC, fpexc & ~FPEXC_EN); |
465 | 461 | ||
466 | /* | 462 | /* |
467 | * Set the context to NULL to force a reload the next time the thread | 463 | * Set the context to NULL to force a reload the next time |
468 | * uses the VFP. | 464 | * the thread uses the VFP. |
469 | */ | 465 | */ |
470 | last_VFP_context[cpu] = NULL; | 466 | last_VFP_context[cpu] = NULL; |
467 | } | ||
471 | 468 | ||
472 | out: | ||
473 | put_cpu(); | 469 | put_cpu(); |
474 | } | 470 | } |
475 | #endif | 471 | #endif |