Skip to content

Commit 41d49d4

Browse files
bp3tk0vgregkh
authored andcommitted
x86/process: Move the buffer clearing before MONITOR
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 <[email protected]>. Suggested-by: Andrew Cooper <[email protected]> Signed-off-by: Borislav Petkov (AMD) <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 5c30f03 commit 41d49d4

File tree

2 files changed

+23
-8
lines changed

2 files changed

+23
-8
lines changed

arch/x86/include/asm/mwait.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,6 @@ static inline void __monitorx(const void *eax, unsigned long ecx,
4444

4545
static inline void __mwait(unsigned long eax, unsigned long ecx)
4646
{
47-
x86_idle_clear_cpu_buffers();
48-
4947
/* "mwait %eax, %ecx;" */
5048
asm volatile(".byte 0x0f, 0x01, 0xc9;"
5149
:: "a" (eax), "c" (ecx));
@@ -89,7 +87,6 @@ static inline void __mwaitx(unsigned long eax, unsigned long ebx,
8987

9088
static inline void __sti_mwait(unsigned long eax, unsigned long ecx)
9189
{
92-
x86_idle_clear_cpu_buffers();
9390

9491
/* "mwait %eax, %ecx;" */
9592
asm volatile("sti; .byte 0x0f, 0x01, 0xc9;"
@@ -108,6 +105,11 @@ static inline void __sti_mwait(unsigned long eax, unsigned long ecx)
108105
*/
109106
static inline void mwait_idle_with_hints(unsigned long eax, unsigned long ecx)
110107
{
108+
if (need_resched())
109+
return;
110+
111+
x86_idle_clear_cpu_buffers();
112+
111113
if (static_cpu_has_bug(X86_BUG_MONITOR) || !current_set_polling_and_test()) {
112114
if (static_cpu_has_bug(X86_BUG_CLFLUSH_MONITOR)) {
113115
mb();
@@ -116,9 +118,13 @@ static inline void mwait_idle_with_hints(unsigned long eax, unsigned long ecx)
116118
}
117119

118120
__monitor((void *)&current_thread_info()->flags, 0, 0);
119-
if (!need_resched())
120-
__mwait(eax, ecx);
121+
if (need_resched())
122+
goto out;
123+
124+
__mwait(eax, ecx);
121125
}
126+
127+
out:
122128
current_clr_polling();
123129
}
124130

arch/x86/kernel/process.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,11 @@ static int prefer_mwait_c1_over_halt(const struct cpuinfo_x86 *c)
887887
*/
888888
static __cpuidle void mwait_idle(void)
889889
{
890+
if (need_resched())
891+
return;
892+
893+
x86_idle_clear_cpu_buffers();
894+
890895
if (!current_set_polling_and_test()) {
891896
if (this_cpu_has(X86_BUG_CLFLUSH_MONITOR)) {
892897
mb(); /* quirk */
@@ -895,13 +900,17 @@ static __cpuidle void mwait_idle(void)
895900
}
896901

897902
__monitor((void *)&current_thread_info()->flags, 0, 0);
898-
if (!need_resched())
899-
__sti_mwait(0, 0);
900-
else
903+
if (need_resched()) {
901904
raw_local_irq_enable();
905+
goto out;
906+
}
907+
908+
__sti_mwait(0, 0);
902909
} else {
903910
raw_local_irq_enable();
904911
}
912+
913+
out:
905914
__current_clr_polling();
906915
}
907916

0 commit comments

Comments
 (0)