aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/entry/vdso/vclock_gettime.c15
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)
128{ 128{
129 if (mode == VCLOCK_TSC) 129 if (mode == VCLOCK_TSC)
130 return (u64)rdtsc_ordered(); 130 return (u64)rdtsc_ordered();
131
132 /*
133 * For any memory-mapped vclock type, we need to make sure that gcc
134 * doesn't cleverly hoist a load before the mode check. Otherwise we
135 * might end up touching the memory-mapped page even if the vclock in
136 * question isn't enabled, which will segfault. Hence the barriers.
137 */
131#ifdef CONFIG_PARAVIRT_CLOCK 138#ifdef CONFIG_PARAVIRT_CLOCK
132 else if (mode == VCLOCK_PVCLOCK) 139 if (mode == VCLOCK_PVCLOCK) {
140 barrier();
133 return vread_pvclock(); 141 return vread_pvclock();
142 }
134#endif 143#endif
135#ifdef CONFIG_HYPERV_TSCPAGE 144#ifdef CONFIG_HYPERV_TSCPAGE
136 else if (mode == VCLOCK_HVCLOCK) 145 if (mode == VCLOCK_HVCLOCK) {
146 barrier();
137 return vread_hvclock(); 147 return vread_hvclock();
148 }
138#endif 149#endif
139 return U64_MAX; 150 return U64_MAX;
140} 151}