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) | |||
| 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 | } |
