diff options
| -rw-r--r-- | arch/x86/entry/vdso/vclock_gettime.c | 15 | 
1 files changed, 13 insertions, 2 deletions
| diff --git a/arch/x86/entry/vdso/vclock_gettime.c b/arch/x86/entry/vdso/vclock_gettime.c index 0f82a70c7682..4aed41f638bb 100644 --- a/arch/x86/entry/vdso/vclock_gettime.c +++ b/arch/x86/entry/vdso/vclock_gettime.c @@ -128,13 +128,24 @@ notrace static inline u64 vgetcyc(int mode)  {  	if (mode == VCLOCK_TSC)  		return (u64)rdtsc_ordered(); + +	/* +	 * For any memory-mapped vclock type, we need to make sure that gcc +	 * doesn't cleverly hoist a load before the mode check.  Otherwise we +	 * might end up touching the memory-mapped page even if the vclock in +	 * question isn't enabled, which will segfault.  Hence the barriers. +	 */  #ifdef CONFIG_PARAVIRT_CLOCK -	else if (mode == VCLOCK_PVCLOCK) +	if (mode == VCLOCK_PVCLOCK) { +		barrier();  		return vread_pvclock(); +	}  #endif  #ifdef CONFIG_HYPERV_TSCPAGE -	else if (mode == VCLOCK_HVCLOCK) +	if (mode == VCLOCK_HVCLOCK) { +		barrier();  		return vread_hvclock(); +	}  #endif  	return U64_MAX;  } |