From mboxrd@z Thu Jan 1 00:00:00 1970 From: Marcelo Tosatti Subject: [patch 05/18] x86: pvclock: fix flags usage race Date: Wed, 24 Oct 2012 11:13:45 -0200 Message-ID: <20121024131621.525794027@redhat.com> References: <20121024131340.742340256@redhat.com> Cc: johnstul@us.ibm.com, jeremy@goop.org, glommer@parallels.com, zamsden@gmail.com, gleb@redhat.com, avi@redhat.com, pbonzini@redhat.com, Marcelo Tosatti To: kvm@vger.kernel.org Return-path: Received: from mx1.redhat.com ([209.132.183.28]:1255 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753307Ab2JXNQx (ORCPT ); Wed, 24 Oct 2012 09:16:53 -0400 Content-Disposition: inline; filename=04-pvclock-read-cycles-return-flags Sender: kvm-owner@vger.kernel.org List-ID: Validity of values returned by pvclock (including flags) is guaranteed by version checks. That is, read of src->flags outside version check protection can refer to a different paravirt clock update by the hypervisor. Signed-off-by: Marcelo Tosatti Index: vsyscall/arch/x86/include/asm/pvclock.h =================================================================== --- vsyscall.orig/arch/x86/include/asm/pvclock.h +++ vsyscall/arch/x86/include/asm/pvclock.h @@ -66,18 +66,21 @@ u64 pvclock_get_nsec_offset(const struct static __always_inline unsigned __pvclock_read_cycles(const struct pvclock_vcpu_time_info *src, - cycle_t *cycles) + cycle_t *cycles, u8 *flags) { unsigned version; cycle_t ret, offset; + u8 ret_flags; version = src->version; rdtsc_barrier(); offset = pvclock_get_nsec_offset(src); ret = src->system_time + offset; + ret_flags = src->flags; rdtsc_barrier(); *cycles = ret; + *flags = ret_flags; return version; } Index: vsyscall/arch/x86/kernel/pvclock.c =================================================================== --- vsyscall.orig/arch/x86/kernel/pvclock.c +++ vsyscall/arch/x86/kernel/pvclock.c @@ -50,13 +50,14 @@ cycle_t pvclock_clocksource_read(struct unsigned version; cycle_t ret; u64 last; + u8 flags; do { - version = __pvclock_read_cycles(src, &ret); + version = __pvclock_read_cycles(src, &ret, &flags); } while ((src->version & 1) || version != src->version); if ((valid_flags & PVCLOCK_TSC_STABLE_BIT) && - (src->flags & PVCLOCK_TSC_STABLE_BIT)) + (flags & PVCLOCK_TSC_STABLE_BIT)) return ret; /*