6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Borislav Petkov (AMD)" bp@alien8.de
Commit 8e786a85c0a3c0fffae6244733fb576eeabd9dec upstream.
Move the VERW clearing before the MONITOR so that VERW doesn't disarm it and the machine never enters C1.
Original idea by Kim Phillips kim.phillips@amd.com.
Suggested-by: Andrew Cooper andrew.cooper3@citrix.com Signed-off-by: Borislav Petkov (AMD) bp@alien8.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/include/asm/mwait.h | 16 +++++++++++----- arch/x86/kernel/process.c | 15 ++++++++++++--- 2 files changed, 23 insertions(+), 8 deletions(-)
--- a/arch/x86/include/asm/mwait.h +++ b/arch/x86/include/asm/mwait.h @@ -44,8 +44,6 @@ static inline void __monitorx(const void
static inline void __mwait(unsigned long eax, unsigned long ecx) { - x86_idle_clear_cpu_buffers(); - /* "mwait %eax, %ecx;" */ asm volatile(".byte 0x0f, 0x01, 0xc9;" :: "a" (eax), "c" (ecx)); @@ -89,7 +87,6 @@ static inline void __mwaitx(unsigned lon
static inline void __sti_mwait(unsigned long eax, unsigned long ecx) { - x86_idle_clear_cpu_buffers();
/* "mwait %eax, %ecx;" */ asm volatile("sti; .byte 0x0f, 0x01, 0xc9;" @@ -108,6 +105,11 @@ static inline void __sti_mwait(unsigned */ static inline void mwait_idle_with_hints(unsigned long eax, unsigned long ecx) { + if (need_resched()) + return; + + x86_idle_clear_cpu_buffers(); + if (static_cpu_has_bug(X86_BUG_MONITOR) || !current_set_polling_and_test()) { if (static_cpu_has_bug(X86_BUG_CLFLUSH_MONITOR)) { mb(); @@ -116,9 +118,13 @@ static inline void mwait_idle_with_hints }
__monitor((void *)¤t_thread_info()->flags, 0, 0); - if (!need_resched()) - __mwait(eax, ecx); + if (need_resched()) + goto out; + + __mwait(eax, ecx); } + +out: current_clr_polling(); }
--- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -887,6 +887,11 @@ static int prefer_mwait_c1_over_halt(con */ static __cpuidle void mwait_idle(void) { + if (need_resched()) + return; + + x86_idle_clear_cpu_buffers(); + if (!current_set_polling_and_test()) { if (this_cpu_has(X86_BUG_CLFLUSH_MONITOR)) { mb(); /* quirk */ @@ -895,13 +900,17 @@ static __cpuidle void mwait_idle(void) }
__monitor((void *)¤t_thread_info()->flags, 0, 0); - if (!need_resched()) - __sti_mwait(0, 0); - else + if (need_resched()) { raw_local_irq_enable(); + goto out; + } + + __sti_mwait(0, 0); } else { raw_local_irq_enable(); } + +out: __current_clr_polling(); }