--- drivers/cpufreq/intel_pstate.c | 53 ++++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 11 deletions(-) --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -897,11 +897,19 @@ static ssize_t show_base_frequency(struc cpufreq_freq_attr_ro(base_frequency); +enum hwp_cpufreq_attr_index { + HWP_BASE_FREQUENCY_INDEX = 0, + HWP_PERFORMANCE_PREFERENCE_INDEX, + HWP_PERFORMANCE_AVAILABLE_PREFERENCES_INDEX, + HWP_CPUFREQ_ATTR_COUNT, +}; + static struct freq_attr *hwp_cpufreq_attrs[] = { - &energy_performance_preference, - &energy_performance_available_preferences, - &base_frequency, - NULL, + [HWP_BASE_FREQUENCY_INDEX] = &base_frequency, + [HWP_PERFORMANCE_PREFERENCE_INDEX] = &energy_performance_preference, + [HWP_PERFORMANCE_AVAILABLE_PREFERENCES_INDEX] = + &energy_performance_available_preferences, + [HWP_CPUFREQ_ATTR_COUNT] = NULL, }; static bool no_cas __ro_after_init; @@ -1370,6 +1378,9 @@ static void intel_pstate_hwp_offline(str #define POWER_CTL_EE_ENABLE 1 #define POWER_CTL_EE_DISABLE 2 +/* Enable bit for Dynamic Efficiency Control (DEC) */ +#define POWER_CTL_DEC_ENABLE 27 + static int power_ctl_ee_state; static void set_power_ctl_ee_state(bool input) @@ -3759,6 +3770,30 @@ static const struct x86_cpu_id intel_hyb {} }; +static bool hwp_is_supported(void) +{ + u64 power_ctl; + + /* + * Avoid enabling HWP for processors without EPP support unless the + * Dynamic Efficiency Control (DEC) enable bit (MSR_IA32_POWER_CTL, + * bit 27) is set because that means incomplete HWP implementation + * which is a corner case and supporting it is generally problematic. + */ + if (boot_cpu_has(X86_FEATURE_HWP_EPP)) + return true; + + rdmsrq(MSR_IA32_POWER_CTL, power_ctl); + if (!(power_ctl & BIT(POWER_CTL_DEC_ENABLE))) + return false; + + /* Without EPP support, don't expose EPP-related sysfs attributes. */ + hwp_cpufreq_attrs[HWP_PERFORMANCE_PREFERENCE_INDEX] = NULL; + hwp_cpufreq_attrs[HWP_PERFORMANCE_AVAILABLE_PREFERENCES_INDEX] = NULL; + + return true; +} + static int __init intel_pstate_init(void) { static struct cpudata **_all_cpu_data; @@ -3788,14 +3823,10 @@ static int __init intel_pstate_init(void copy_cpu_funcs(&core_funcs); /* - * Avoid enabling HWP for processors without EPP support, - * because that means incomplete HWP implementation which is a - * corner case and supporting it is generally problematic. - * - * If HWP is enabled already, though, there is no choice but to - * deal with it. + * If HWP is enabled already, there is no choice but to deal + * with it. */ - if ((!no_hwp && boot_cpu_has(X86_FEATURE_HWP_EPP)) || hwp_forced) { + if (hwp_forced || (!no_hwp && hwp_is_supported())) { hwp_active = true; hwp_mode_bdw = id->driver_data; intel_pstate.attr = hwp_cpufreq_attrs;