aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndre Przywara <andre.przywara@amd.com>2012-05-29 07:07:31 -0400
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2012-05-31 12:16:52 -0400
commit5e626254206a709c6e937f3dda69bf26c7344f6f (patch)
tree3518e8efbca67bcd44d922b7c3ef758ffee6fbd0
parent58b7b53a36b0be8081fbfc91aeea24b83c20ca1b (diff)
xen/setup: filter APERFMPERF cpuid feature out
Xen PV kernels allow access to the APERF/MPERF registers to read the effective frequency. Access to the MSRs is however redirected to the currently scheduled physical CPU, making consecutive read and compares unreliable. In addition each rdmsr traps into the hypervisor. So to avoid bogus readouts and expensive traps, disable the kernel internal feature flag for APERF/MPERF if running under Xen. This will a) remove the aperfmperf flag from /proc/cpuinfo b) not mislead the power scheduler (arch/x86/kernel/cpu/sched.c) to use the feature to improve scheduling (by default disabled) c) not mislead the cpufreq driver to use the MSRs This does not cover userland programs which access the MSRs via the device file interface, but this will be addressed separately. Signed-off-by: Andre Przywara <andre.przywara@amd.com> Cc: stable@vger.kernel.org # v3.0+ Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
-rw-r--r--arch/x86/xen/enlighten.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index d1f9a0472d44..272ebd0ce326 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -208,6 +208,9 @@ static void __init xen_banner(void)
208 xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " (preserve-AD)" : ""); 208 xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " (preserve-AD)" : "");
209} 209}
210 210
211#define CPUID_THERM_POWER_LEAF 6
212#define APERFMPERF_PRESENT 0
213
211static __read_mostly unsigned int cpuid_leaf1_edx_mask = ~0; 214static __read_mostly unsigned int cpuid_leaf1_edx_mask = ~0;
212static __read_mostly unsigned int cpuid_leaf1_ecx_mask = ~0; 215static __read_mostly unsigned int cpuid_leaf1_ecx_mask = ~0;
213 216
@@ -241,6 +244,11 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx,
241 *dx = cpuid_leaf5_edx_val; 244 *dx = cpuid_leaf5_edx_val;
242 return; 245 return;
243 246
247 case CPUID_THERM_POWER_LEAF:
248 /* Disabling APERFMPERF for kernel usage */
249 maskecx = ~(1 << APERFMPERF_PRESENT);
250 break;
251
244 case 0xb: 252 case 0xb:
245 /* Suppress extended topology stuff */ 253 /* Suppress extended topology stuff */
246 maskebx = 0; 254 maskebx = 0;