kvm/powerpc/e500mc: fix tlb invalidation on cpu migration

Submitted by Scott Wood on Feb. 19, 2013, 4:13 a.m.

Details

Message ID 20130219041309.GA17075@home.buserror.net
State New
Headers show

Commit Message

Scott Wood Feb. 19, 2013, 4:13 a.m.
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.

Signed-off-by: Scott Wood <scottwood@freescale.com>
---
This seems to have been the cause of the userspace segfaults I was
seeing (the other TLB patches I posted are still needed as well).

 arch/powerpc/kvm/e500mc.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

Comments

Alexander Graf March 8, 2013, 12:11 p.m.
On 19.02.2013, at 05:13, Scott Wood wrote:

> 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.
> 
> Signed-off-by: Scott Wood <scottwood@freescale.com>
> ---
> This seems to have been the cause of the userspace segfaults I was
> seeing (the other TLB patches I posted are still needed as well).
> 
> arch/powerpc/kvm/e500mc.c |    6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
> index 1f89d26..8637689 100644
> --- a/arch/powerpc/kvm/e500mc.c
> +++ b/arch/powerpc/kvm/e500mc.c
> @@ -111,6 +111,7 @@ void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr)
> void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
> {
> 	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
> +	static struct kvm_vcpu *last_vcpu_on_cpu[NR_CPUS];

Why not use DEFINE_PER_CPU?


Alex

> 
> 	kvmppc_booke_vcpu_load(vcpu, cpu);
> 
> @@ -136,8 +137,11 @@ void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
> 	mtspr(SPRN_GDEAR, vcpu->arch.shared->dar);
> 	mtspr(SPRN_GESR, vcpu->arch.shared->esr);
> 
> -	if (vcpu->arch.oldpir != mfspr(SPRN_PIR))
> +	if (vcpu->arch.oldpir != mfspr(SPRN_PIR) ||
> +	    last_vcpu_on_cpu[smp_processor_id()] != vcpu) {
> 		kvmppc_e500_tlbil_all(vcpu_e500);
> +		last_vcpu_on_cpu[smp_processor_id()] = vcpu;
> +	}
> 
> 	kvmppc_load_guest_fp(vcpu);
> }
> -- 
> 1.7.9.5
> 

--
To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch hide | download patch | download mbox

diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c
index 1f89d26..8637689 100644
--- a/arch/powerpc/kvm/e500mc.c
+++ b/arch/powerpc/kvm/e500mc.c
@@ -111,6 +111,7 @@  void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr)
 void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 {
 	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+	static struct kvm_vcpu *last_vcpu_on_cpu[NR_CPUS];
 
 	kvmppc_booke_vcpu_load(vcpu, cpu);
 
@@ -136,8 +137,11 @@  void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 	mtspr(SPRN_GDEAR, vcpu->arch.shared->dar);
 	mtspr(SPRN_GESR, vcpu->arch.shared->esr);
 
-	if (vcpu->arch.oldpir != mfspr(SPRN_PIR))
+	if (vcpu->arch.oldpir != mfspr(SPRN_PIR) ||
+	    last_vcpu_on_cpu[smp_processor_id()] != vcpu) {
 		kvmppc_e500_tlbil_all(vcpu_e500);
+		last_vcpu_on_cpu[smp_processor_id()] = vcpu;
+	}
 
 	kvmppc_load_guest_fp(vcpu);
 }