Commit ecf9b7bf authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'x86_core_for_v6.0_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 core updates from Borislav Petkov:

 - Have invalid MSR accesses warnings appear only once after a
   pr_warn_once() change broke that

 - Simplify {JMP,CALL}_NOSPEC and let the objtool retpoline patching
   infra take care of them instead of having unreadable alternative
   macros there

* tag 'x86_core_for_v6.0_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/extable: Fix ex_handler_msr() print condition
  x86,nospec: Simplify {JMP,CALL}_NOSPEC
parents 98b1783d a1a5482a
...@@ -93,6 +93,19 @@ ...@@ -93,6 +93,19 @@
#endif #endif
.endm .endm
/*
* Equivalent to -mindirect-branch-cs-prefix; emit the 5 byte jmp/call
* to the retpoline thunk with a CS prefix when the register requires
* a RAX prefix byte to encode. Also see apply_retpolines().
*/
.macro __CS_PREFIX reg:req
.irp rs,r8,r9,r10,r11,r12,r13,r14,r15
.ifc \reg,\rs
.byte 0x2e
.endif
.endr
.endm
/* /*
* JMP_NOSPEC and CALL_NOSPEC macros can be used instead of a simple * JMP_NOSPEC and CALL_NOSPEC macros can be used instead of a simple
* indirect jmp/call which may be susceptible to the Spectre variant 2 * indirect jmp/call which may be susceptible to the Spectre variant 2
...@@ -100,19 +113,18 @@ ...@@ -100,19 +113,18 @@
*/ */
.macro JMP_NOSPEC reg:req .macro JMP_NOSPEC reg:req
#ifdef CONFIG_RETPOLINE #ifdef CONFIG_RETPOLINE
ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), \ __CS_PREFIX \reg
__stringify(jmp __x86_indirect_thunk_\reg), X86_FEATURE_RETPOLINE, \ jmp __x86_indirect_thunk_\reg
__stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), X86_FEATURE_RETPOLINE_LFENCE
#else #else
jmp *%\reg jmp *%\reg
int3
#endif #endif
.endm .endm
.macro CALL_NOSPEC reg:req .macro CALL_NOSPEC reg:req
#ifdef CONFIG_RETPOLINE #ifdef CONFIG_RETPOLINE
ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; call *%\reg), \ __CS_PREFIX \reg
__stringify(call __x86_indirect_thunk_\reg), X86_FEATURE_RETPOLINE, \ call __x86_indirect_thunk_\reg
__stringify(lfence; ANNOTATE_RETPOLINE_SAFE; call *%\reg), X86_FEATURE_RETPOLINE_LFENCE
#else #else
call *%\reg call *%\reg
#endif #endif
......
...@@ -94,16 +94,18 @@ static bool ex_handler_copy(const struct exception_table_entry *fixup, ...@@ -94,16 +94,18 @@ static bool ex_handler_copy(const struct exception_table_entry *fixup,
static bool ex_handler_msr(const struct exception_table_entry *fixup, static bool ex_handler_msr(const struct exception_table_entry *fixup,
struct pt_regs *regs, bool wrmsr, bool safe, int reg) struct pt_regs *regs, bool wrmsr, bool safe, int reg)
{ {
if (!safe && wrmsr && if (__ONCE_LITE_IF(!safe && wrmsr)) {
pr_warn_once("unchecked MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x) at rIP: 0x%lx (%pS)\n", pr_warn("unchecked MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x) at rIP: 0x%lx (%pS)\n",
(unsigned int)regs->cx, (unsigned int)regs->dx, (unsigned int)regs->cx, (unsigned int)regs->dx,
(unsigned int)regs->ax, regs->ip, (void *)regs->ip)) (unsigned int)regs->ax, regs->ip, (void *)regs->ip);
show_stack_regs(regs); show_stack_regs(regs);
}
if (!safe && !wrmsr && if (__ONCE_LITE_IF(!safe && !wrmsr)) {
pr_warn_once("unchecked MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pS)\n", pr_warn("unchecked MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pS)\n",
(unsigned int)regs->cx, regs->ip, (void *)regs->ip)) (unsigned int)regs->cx, regs->ip, (void *)regs->ip);
show_stack_regs(regs); show_stack_regs(regs);
}
if (!wrmsr) { if (!wrmsr) {
/* Pretend that the read succeeded and returned 0. */ /* Pretend that the read succeeded and returned 0. */
......
...@@ -9,15 +9,27 @@ ...@@ -9,15 +9,27 @@
*/ */
#define DO_ONCE_LITE(func, ...) \ #define DO_ONCE_LITE(func, ...) \
DO_ONCE_LITE_IF(true, func, ##__VA_ARGS__) DO_ONCE_LITE_IF(true, func, ##__VA_ARGS__)
#define DO_ONCE_LITE_IF(condition, func, ...) \
#define __ONCE_LITE_IF(condition) \
({ \ ({ \
static bool __section(".data.once") __already_done; \ static bool __section(".data.once") __already_done; \
bool __ret_do_once = !!(condition); \ bool __ret_cond = !!(condition); \
bool __ret_once = false; \
\ \
if (unlikely(__ret_do_once && !__already_done)) { \ if (unlikely(__ret_cond && !__already_done)) { \
__already_done = true; \ __already_done = true; \
func(__VA_ARGS__); \ __ret_once = true; \
} \ } \
unlikely(__ret_once); \
})
#define DO_ONCE_LITE_IF(condition, func, ...) \
({ \
bool __ret_do_once = !!(condition); \
\
if (__ONCE_LITE_IF(__ret_do_once)) \
func(__VA_ARGS__); \
\
unlikely(__ret_do_once); \ unlikely(__ret_do_once); \
}) })
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment