|
@@ -829,6 +829,9 @@ static void init_amd(struct cpuinfo_x86 *c)
|
|
|
set_cpu_cap(c, X86_FEATURE_K8);
|
|
|
|
|
|
if (cpu_has(c, X86_FEATURE_XMM2)) {
|
|
|
+ unsigned long long val;
|
|
|
+ int ret;
|
|
|
+
|
|
|
/*
|
|
|
* A serializing LFENCE has less overhead than MFENCE, so
|
|
|
* use it for execution serialization. On families which
|
|
@@ -839,8 +842,19 @@ static void init_amd(struct cpuinfo_x86 *c)
|
|
|
msr_set_bit(MSR_F10H_DECFG,
|
|
|
MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT);
|
|
|
|
|
|
- /* MFENCE stops RDTSC speculation */
|
|
|
- set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC);
|
|
|
+ /*
|
|
|
+ * Verify that the MSR write was successful (could be running
|
|
|
+ * under a hypervisor) and only then assume that LFENCE is
|
|
|
+ * serializing.
|
|
|
+ */
|
|
|
+ ret = rdmsrl_safe(MSR_F10H_DECFG, &val);
|
|
|
+ if (!ret && (val & MSR_F10H_DECFG_LFENCE_SERIALIZE)) {
|
|
|
+ /* A serializing LFENCE stops RDTSC speculation */
|
|
|
+ set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
|
|
|
+ } else {
|
|
|
+ /* MFENCE stops RDTSC speculation */
|
|
|
+ set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/*
|