From mboxrd@z Thu Jan 1 00:00:00 1970 From: Marcelo Tosatti Subject: Re: [PATCH] x86: vdso: fix pvclock races with task migration Date: Mon, 6 Apr 2015 17:57:16 -0300 Message-ID: <20150406205716.GA1896@amt.cnet> References: <1428000263-11892-1-git-send-email-rkrcmar@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: QUOTED-PRINTABLE Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, Paolo Bonzini , Andy Lutomirski , stable@vger.kernel.org To: Radim =?utf-8?B?S3LEjW3DocWZ?= Return-path: Content-Disposition: inline In-Reply-To: <1428000263-11892-1-git-send-email-rkrcmar@redhat.com> Sender: stable-owner@vger.kernel.org List-Id: kvm.vger.kernel.org On Thu, Apr 02, 2015 at 08:44:23PM +0200, Radim Kr=C4=8Dm=C3=A1=C5=99 w= rote: > If we were migrated right after __getcpu, but before reading the > migration_count, we wouldn't notice that we read TSC of a different > VCPU, nor that KVM's bug made pvti invalid, as only migration_count > on source VCPU is increased. >=20 > Change vdso instead of updating migration_count on destination. >=20 > Fixes: 0a4e6be9ca17 ("x86: kvm: Revert "remove sched notifier for cro= ss-cpu migrations"") > Cc: stable@vger.kernel.org > Signed-off-by: Radim Kr=C4=8Dm=C3=A1=C5=99 > --- > Because it we'll get a complete rewrite, this series does not > - remove the outdated 'TODO: We can put [...]' comment > - use a proper encapsulation for the inner do-while loop > - optimize the outer do-while loop > (no need to re-read cpu id on version mismatch) >=20 > arch/x86/vdso/vclock_gettime.c | 20 ++++++++++++-------- > 1 file changed, 12 insertions(+), 8 deletions(-) >=20 > diff --git a/arch/x86/vdso/vclock_gettime.c b/arch/x86/vdso/vclock_ge= ttime.c > index 30933760ee5f..40d2473836c9 100644 > --- a/arch/x86/vdso/vclock_gettime.c > +++ b/arch/x86/vdso/vclock_gettime.c > @@ -99,21 +99,25 @@ static notrace cycle_t vread_pvclock(int *mode) > * __getcpu() calls (Gleb). > */ > =20 > - pvti =3D get_pvti(cpu); > + /* Make sure migrate_count will change if we leave the VCPU. */ > + do { > + pvti =3D get_pvti(cpu); > + migrate_count =3D pvti->migrate_count; > =20 > - migrate_count =3D pvti->migrate_count; > + cpu1 =3D cpu; > + cpu =3D __getcpu() & VGETCPU_CPU_MASK; > + } while (unlikely(cpu !=3D cpu1)); > =20 > version =3D __pvclock_read_cycles(&pvti->pvti, &ret, &flags); > =20 > /* > * Test we're still on the cpu as well as the version. > - * We could have been migrated just after the first > - * vgetcpu but before fetching the version, so we > - * wouldn't notice a version change. > + * - We must read TSC of pvti's VCPU. > + * - KVM doesn't follow the versioning protocol, so data could > + * change before version if we left the VCPU. > */ > - cpu1 =3D __getcpu() & VGETCPU_CPU_MASK; > - } while (unlikely(cpu !=3D cpu1 || > - (pvti->pvti.version & 1) || > + smp_rmb(); > + } while (unlikely((pvti->pvti.version & 1) || > pvti->pvti.version !=3D version || > pvti->migrate_count !=3D migrate_count)); > =20 > --=20 > 2.3.4 >=20 > -- > To unsubscribe from this list: send the line "unsubscribe kvm" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html Reviewed-by: Marcelo Tosatti