diff options
author | Anton Blanchard <anton@samba.org> | 2015-10-29 01:44:09 +0100 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2015-12-02 09:34:40 +0100 |
commit | 579e633e764e6e5f7784b74e7df3e81fe11f40de (patch) | |
tree | b2c0152e295aaee02ffe74eba1b567b404115593 /arch | |
parent | powerpc: create giveup_all() (diff) | |
download | linux-579e633e764e6e5f7784b74e7df3e81fe11f40de.tar.xz linux-579e633e764e6e5f7784b74e7df3e81fe11f40de.zip |
powerpc: create flush_all_to_thread()
Create a single function that flushes everything (FP, VMX, VSX, SPE).
Doing this all at once means we only do one MSR write.
Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/include/asm/switch_to.h | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/process.c | 22 | ||||
-rw-r--r-- | arch/powerpc/kernel/swsusp.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_hv.c | 5 |
4 files changed, 22 insertions, 10 deletions
diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h index 8f856788a7cf..81d46a433c03 100644 --- a/arch/powerpc/include/asm/switch_to.h +++ b/arch/powerpc/include/asm/switch_to.h @@ -27,6 +27,7 @@ extern void giveup_vsx(struct task_struct *); extern void enable_kernel_spe(void); extern void load_up_spe(struct task_struct *); extern void giveup_all(struct task_struct *); +extern void flush_all_to_thread(struct task_struct *); extern void switch_booke_debug_regs(struct debug_reg *new_debug); #ifdef CONFIG_PPC_FPU diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 4c087b9ed2d6..7f437e7b273e 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -367,6 +367,23 @@ void giveup_all(struct task_struct *tsk) } EXPORT_SYMBOL(giveup_all); +void flush_all_to_thread(struct task_struct *tsk) +{ + if (tsk->thread.regs) { + preempt_disable(); + BUG_ON(tsk != current); + giveup_all(tsk); + +#ifdef CONFIG_SPE + if (tsk->thread.regs->msr & MSR_SPE) + tsk->thread.spefscr = mfspr(SPRN_SPEFSCR); +#endif + + preempt_enable(); + } +} +EXPORT_SYMBOL(flush_all_to_thread); + #ifdef CONFIG_PPC_ADV_DEBUG_REGS void do_send_trap(struct pt_regs *regs, unsigned long address, unsigned long error_code, int signal_code, int breakpt) @@ -1137,10 +1154,7 @@ release_thread(struct task_struct *t) */ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) { - flush_fp_to_thread(src); - flush_altivec_to_thread(src); - flush_vsx_to_thread(src); - flush_spe_to_thread(src); + flush_all_to_thread(src); /* * Flush TM state out so we can copy it. __switch_to_tm() does this * flush but it removes the checkpointed state from the current CPU and diff --git a/arch/powerpc/kernel/swsusp.c b/arch/powerpc/kernel/swsusp.c index eae33e10b65f..6669b1752512 100644 --- a/arch/powerpc/kernel/swsusp.c +++ b/arch/powerpc/kernel/swsusp.c @@ -20,9 +20,7 @@ void save_processor_state(void) * flush out all the special registers so we don't need * to save them in the snapshot */ - flush_fp_to_thread(current); - flush_altivec_to_thread(current); - flush_spe_to_thread(current); + flush_all_to_thread(current); #ifdef CONFIG_PPC64 hard_irq_disable(); diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 54b45b73195f..8e694707bc56 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -2700,9 +2700,8 @@ static int kvmppc_vcpu_run_hv(struct kvm_run *run, struct kvm_vcpu *vcpu) goto out; } - flush_fp_to_thread(current); - flush_altivec_to_thread(current); - flush_vsx_to_thread(current); + flush_all_to_thread(current); + vcpu->arch.wqp = &vcpu->arch.vcore->wq; vcpu->arch.pgdir = current->mm->pgd; vcpu->arch.state = KVMPPC_VCPU_BUSY_IN_HOST; |