aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm/e500mc.c
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2013-02-18 13:13:09 -0500
committerAlexander Graf <agraf@suse.de>2013-04-10 18:06:39 -0400
commitc5e6cb051c5f7d56f05bd6a4af22cb300a4ced79 (patch)
treeeb54ebc8dcbefa69f08e40c8865b5cc18ea37b01 /arch/powerpc/kvm/e500mc.c
parent31880c37c11e28cb81c70757e38392b42e695dc6 (diff)
kvm/powerpc/e500mc: fix tlb invalidation on cpu migration
The existing check handles the case where we've migrated to a different core than we last ran on, but it doesn't handle the case where we're still on the same cpu we last ran on, but some other vcpu has run on this cpu in the meantime. Without this, guest segfaults (and other misbehavior) have been seen in smp guests. Cc: stable@vger.kernel.org # 3.8.x Signed-off-by: Scott Wood <scottwood@freescale.com> Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'arch/powerpc/kvm/e500mc.c')
-rw-r--r--arch/powerpc/kvm/e500mc.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
index 1f89d26e65fb..2f4baa074b2e 100644
--- a/arch/powerpc/kvm/e500mc.c
+++ b/arch/powerpc/kvm/e500mc.c
@@ -108,6 +108,8 @@ void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr)
108{ 108{
109} 109}
110 110
111static DEFINE_PER_CPU(struct kvm_vcpu *, last_vcpu_on_cpu);
112
111void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) 113void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
112{ 114{
113 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); 115 struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
@@ -136,8 +138,11 @@ void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
136 mtspr(SPRN_GDEAR, vcpu->arch.shared->dar); 138 mtspr(SPRN_GDEAR, vcpu->arch.shared->dar);
137 mtspr(SPRN_GESR, vcpu->arch.shared->esr); 139 mtspr(SPRN_GESR, vcpu->arch.shared->esr);
138 140
139 if (vcpu->arch.oldpir != mfspr(SPRN_PIR)) 141 if (vcpu->arch.oldpir != mfspr(SPRN_PIR) ||
142 __get_cpu_var(last_vcpu_on_cpu) != vcpu) {
140 kvmppc_e500_tlbil_all(vcpu_e500); 143 kvmppc_e500_tlbil_all(vcpu_e500);
144 __get_cpu_var(last_vcpu_on_cpu) = vcpu;
145 }
141 146
142 kvmppc_load_guest_fp(vcpu); 147 kvmppc_load_guest_fp(vcpu);
143} 148}