This is a note to let you know that I've just added the patch titled cpuidle,intel_idle: Fix CPUIDLE_FLAG_IRQ_ENABLE to the 5.18-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: cpuidle-intel_idle-fix-cpuidle_flag_irq_enable.patch and it can be found in the queue-5.18 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From 32d4fd5751eadbe1823a37eb38df85ec5c8e6207 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra <peterz@xxxxxxxxxxxxx> Date: Wed, 8 Jun 2022 16:27:27 +0200 Subject: cpuidle,intel_idle: Fix CPUIDLE_FLAG_IRQ_ENABLE From: Peter Zijlstra <peterz@xxxxxxxxxxxxx> commit 32d4fd5751eadbe1823a37eb38df85ec5c8e6207 upstream. Commit c227233ad64c ("intel_idle: enable interrupts before C1 on Xeons") wrecked intel_idle in two ways: - must not have tracing in idle functions - must return with IRQs disabled Additionally, it added a branch for no good reason. Fixes: c227233ad64c ("intel_idle: enable interrupts before C1 on Xeons") Signed-off-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx> [ rjw: Moved the intel_idle() kerneldoc comment next to the function ] Cc: 5.16+ <stable@xxxxxxxxxxxxxxx> # 5.16+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/idle/intel_idle.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -115,6 +115,18 @@ static unsigned int mwait_substates __in #define flg2MWAIT(flags) (((flags) >> 24) & 0xFF) #define MWAIT2flg(eax) ((eax & 0xFF) << 24) +static __always_inline int __intel_idle(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) +{ + struct cpuidle_state *state = &drv->states[index]; + unsigned long eax = flg2MWAIT(state->flags); + unsigned long ecx = 1; /* break on interrupt flag */ + + mwait_idle_with_hints(eax, ecx); + + return index; +} + /** * intel_idle - Ask the processor to enter the given idle state. * @dev: cpuidle device of the target CPU. @@ -132,16 +144,19 @@ static unsigned int mwait_substates __in static __cpuidle int intel_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { - struct cpuidle_state *state = &drv->states[index]; - unsigned long eax = flg2MWAIT(state->flags); - unsigned long ecx = 1; /* break on interrupt flag */ + return __intel_idle(dev, drv, index); +} - if (state->flags & CPUIDLE_FLAG_IRQ_ENABLE) - local_irq_enable(); +static __cpuidle int intel_idle_irq(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) +{ + int ret; - mwait_idle_with_hints(eax, ecx); + raw_local_irq_enable(); + ret = __intel_idle(dev, drv, index); + raw_local_irq_disable(); - return index; + return ret; } /** @@ -1668,6 +1683,9 @@ static void __init intel_idle_init_cstat /* Structure copy. */ drv->states[drv->state_count] = cpuidle_state_table[cstate]; + if (cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_IRQ_ENABLE) + drv->states[drv->state_count].enter = intel_idle_irq; + if ((disabled_states_mask & BIT(drv->state_count)) || ((icpu->use_acpi || force_use_acpi) && intel_idle_off_by_default(mwait_hint) && Patches currently in stable-queue which might be from peterz@xxxxxxxxxxxxx are queue-5.18/objtool-mark-__ubsan_handle_builtin_unreachable-as-n.patch queue-5.18/x86-cpu-elide-kcsan-for-cpu_has-and-friends.patch queue-5.18/cpuidle-intel_idle-fix-cpuidle_flag_irq_enable.patch queue-5.18/perf-parse-events-move-slots-event-for-the-hybrid-pl.patch queue-5.18/jump_label-noinstr-avoid-instrumentation-for-jump_la.patch queue-5.18/perf-c2c-fix-sorting-in-percent_rmt_hitm_cmp.patch queue-5.18/perf-record-support-sample-read-topdown-metric-group.patch queue-5.18/sched-autogroup-fix-sysctl-move.patch queue-5.18/perf-evsel-fixes-topdown-events-in-a-weak-group-for-.patch