Skip to content

Commit c08c866

Browse files
bp3tk0vopsiff
authored andcommitted
x86/process: Move the buffer clearing before MONITOR
Commit 8e786a8 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> (cherry picked from commit 8c1944905855c2ea56dbd21915dce6b802af49be)
1 parent 7c0750e commit c08c866

2 files changed

Lines changed: 27 additions & 14 deletions

File tree

arch/x86/include/asm/mwait.h

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,6 @@ static __always_inline void __monitorx(const void *eax, unsigned long ecx,
4646

4747
static __always_inline void __mwait(unsigned long eax, unsigned long ecx)
4848
{
49-
x86_idle_clear_cpu_buffers();
50-
5149
/* "mwait %eax, %ecx;" */
5250
asm volatile(".byte 0x0f, 0x01, 0xc9;"
5351
:: "a" (eax), "c" (ecx));
@@ -91,7 +89,6 @@ static __always_inline void __mwaitx(unsigned long eax, unsigned long ebx,
9189

9290
static __always_inline void __sti_mwait(unsigned long eax, unsigned long ecx)
9391
{
94-
x86_idle_clear_cpu_buffers();
9592

9693
/* "mwait %eax, %ecx;" */
9794
asm volatile("sti; .byte 0x0f, 0x01, 0xc9;"
@@ -110,21 +107,29 @@ static __always_inline void __sti_mwait(unsigned long eax, unsigned long ecx)
110107
*/
111108
static __always_inline void mwait_idle_with_hints(unsigned long eax, unsigned long ecx)
112109
{
110+
if (need_resched())
111+
return;
112+
113+
x86_idle_clear_cpu_buffers();
114+
113115
if (static_cpu_has_bug(X86_BUG_MONITOR) || !current_set_polling_and_test()) {
114116
const void *addr = &current_thread_info()->flags;
115117

116118
alternative_input("", "clflush (%[addr])", X86_BUG_CLFLUSH_MONITOR, [addr] "a" (addr));
117119
__monitor(addr, 0, 0);
118120

119-
if (!need_resched()) {
120-
if (ecx & 1) {
121-
__mwait(eax, ecx);
122-
} else {
123-
__sti_mwait(eax, ecx);
124-
raw_local_irq_disable();
125-
}
121+
if (need_resched())
122+
goto out;
123+
124+
if (ecx & 1) {
125+
__mwait(eax, ecx);
126+
} else {
127+
__sti_mwait(eax, ecx);
128+
raw_local_irq_disable();
126129
}
127130
}
131+
132+
out:
128133
current_clr_polling();
129134
}
130135

arch/x86/kernel/process.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -928,16 +928,24 @@ static int prefer_mwait_c1_over_halt(const struct cpuinfo_x86 *c)
928928
*/
929929
static __cpuidle void mwait_idle(void)
930930
{
931+
if (need_resched())
932+
return;
933+
934+
x86_idle_clear_cpu_buffers();
935+
931936
if (!current_set_polling_and_test()) {
932937
const void *addr = &current_thread_info()->flags;
933938

934939
alternative_input("", "clflush (%[addr])", X86_BUG_CLFLUSH_MONITOR, [addr] "a" (addr));
935940
__monitor(addr, 0, 0);
936-
if (!need_resched()) {
937-
__sti_mwait(0, 0);
938-
raw_local_irq_disable();
939-
}
941+
if (need_resched())
942+
goto out;
943+
944+
__sti_mwait(0, 0);
945+
raw_local_irq_disable();
940946
}
947+
948+
out:
941949
__current_clr_polling();
942950
}
943951

0 commit comments

Comments
 (0)