| From 5e626254206a709c6e937f3dda69bf26c7344f6f Mon Sep 17 00:00:00 2001 |
| From: Andre Przywara <andre.przywara@amd.com> |
| Date: Tue, 29 May 2012 13:07:31 +0200 |
| Subject: xen/setup: filter APERFMPERF cpuid feature out |
| |
| From: Andre Przywara <andre.przywara@amd.com> |
| |
| commit 5e626254206a709c6e937f3dda69bf26c7344f6f upstream. |
| |
| 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> |
| Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/x86/xen/enlighten.c | 8 ++++++++ |
| 1 file changed, 8 insertions(+) |
| |
| --- a/arch/x86/xen/enlighten.c |
| +++ b/arch/x86/xen/enlighten.c |
| @@ -207,6 +207,9 @@ static void __init xen_banner(void) |
| xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " (preserve-AD)" : ""); |
| } |
| |
| +#define CPUID_THERM_POWER_LEAF 6 |
| +#define APERFMPERF_PRESENT 0 |
| + |
| static __read_mostly unsigned int cpuid_leaf1_edx_mask = ~0; |
| static __read_mostly unsigned int cpuid_leaf1_ecx_mask = ~0; |
| |
| @@ -240,6 +243,11 @@ static void xen_cpuid(unsigned int *ax, |
| *dx = cpuid_leaf5_edx_val; |
| return; |
| |
| + case CPUID_THERM_POWER_LEAF: |
| + /* Disabling APERFMPERF for kernel usage */ |
| + maskecx = ~(1 << APERFMPERF_PRESENT); |
| + break; |
| + |
| case 0xb: |
| /* Suppress extended topology stuff */ |
| maskebx = 0; |