]> git.ipfire.org Git - thirdparty/kernel/stable.git/blobdiff - arch/x86/entry/vdso/vclock_gettime.c
x86/vdso: Prevent segfaults due to hoisted vclock reads
[thirdparty/kernel/stable.git] / arch / x86 / entry / vdso / vclock_gettime.c
index 0f82a70c7682c4973c7ffd1166755fbf01380f44..4aed41f638bb09f8ac575d683583cef6e8c564c9 100644 (file)
@@ -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;
 }