summaryrefslogtreecommitdiffstats
path: root/drivers/idle
diff options
context:
space:
mode:
authorArtem Bityutskiy <artem.bityutskiy@linux.intel.com>2023-04-19 16:39:44 +0200
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2023-04-27 19:37:36 +0200
commit00433eae1771d355f20c152ddc5976baedb427e2 (patch)
tree899f414afc50a8f3051a18fdeae54a6052019029 /drivers/idle
parentintel_idle: further intel_idle_init_cstates_icpu() cleanup (diff)
downloadlinux-00433eae1771d355f20c152ddc5976baedb427e2.tar.xz
linux-00433eae1771d355f20c152ddc5976baedb427e2.zip
intel_idle: improve C-state flags handling robustness
The following C-state flags are currently mutually-exclusive and should not be combined: * IRQ_ENABLE * IBRS * XSTATE There is a warning for the situation when the IRQ_ENABLE flag is combined with the IBRS flag, but no warnings for other combinations. This is inconsistent and prone to errors. Improve the situation by adding warnings for all the unexpected combinations. Add a couple of helpful commentaries too. Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> Reviewed-by: Zhang Rui <rui.zhang@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/idle')
-rw-r--r--drivers/idle/intel_idle.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index 73ddb1d8cfcf..1de36df15d5a 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -1896,20 +1896,28 @@ static void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv)
drv->states[drv->state_count] = cpuidle_state_table[cstate];
state = &drv->states[drv->state_count];
- if ((state->flags & CPUIDLE_FLAG_IRQ_ENABLE) || force_irq_on) {
- pr_info("forced intel_idle_irq for state %d\n", cstate);
- state->enter = intel_idle_irq;
- }
-
- if (cpu_feature_enabled(X86_FEATURE_KERNEL_IBRS) &&
- state->flags & CPUIDLE_FLAG_IBRS) {
+ if (state->flags & CPUIDLE_FLAG_INIT_XSTATE) {
+ /*
+ * Combining with XSTATE with IBRS or IRQ_ENABLE flags
+ * is not currently supported but this driver.
+ */
+ WARN_ON_ONCE(state->flags & CPUIDLE_FLAG_IBRS);
+ WARN_ON_ONCE(state->flags & CPUIDLE_FLAG_IRQ_ENABLE);
+ state->enter = intel_idle_xstate;
+ } else if (cpu_feature_enabled(X86_FEATURE_KERNEL_IBRS) &&
+ state->flags & CPUIDLE_FLAG_IBRS) {
+ /*
+ * IBRS mitigation requires that C-states are entered
+ * with interrupts disabled.
+ */
WARN_ON_ONCE(state->flags & CPUIDLE_FLAG_IRQ_ENABLE);
state->enter = intel_idle_ibrs;
+ } else if ((state->flags & CPUIDLE_FLAG_IRQ_ENABLE) ||
+ force_irq_on) {
+ pr_info("forced intel_idle_irq for state %d\n", cstate);
+ state->enter = intel_idle_irq;
}
- if (state->flags & CPUIDLE_FLAG_INIT_XSTATE)
- state->enter = intel_idle_xstate;
-
if ((disabled_states_mask & BIT(drv->state_count)) ||
((icpu->use_acpi || force_use_acpi) &&
intel_idle_off_by_default(mwait_hint) &&