mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-02 09:16:41 +09:00
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
This commit is contained in:
@@ -93,6 +93,19 @@
|
||||
#endif
|
||||
.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
|
||||
* indirect jmp/call which may be susceptible to the Spectre variant 2
|
||||
@@ -100,19 +113,18 @@
|
||||
*/
|
||||
.macro JMP_NOSPEC reg:req
|
||||
#ifdef CONFIG_RETPOLINE
|
||||
ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), \
|
||||
__stringify(jmp __x86_indirect_thunk_\reg), X86_FEATURE_RETPOLINE, \
|
||||
__stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), X86_FEATURE_RETPOLINE_LFENCE
|
||||
__CS_PREFIX \reg
|
||||
jmp __x86_indirect_thunk_\reg
|
||||
#else
|
||||
jmp *%\reg
|
||||
int3
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro CALL_NOSPEC reg:req
|
||||
#ifdef CONFIG_RETPOLINE
|
||||
ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; call *%\reg), \
|
||||
__stringify(call __x86_indirect_thunk_\reg), X86_FEATURE_RETPOLINE, \
|
||||
__stringify(lfence; ANNOTATE_RETPOLINE_SAFE; call *%\reg), X86_FEATURE_RETPOLINE_LFENCE
|
||||
__CS_PREFIX \reg
|
||||
call __x86_indirect_thunk_\reg
|
||||
#else
|
||||
call *%\reg
|
||||
#endif
|
||||
|
||||
@@ -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,
|
||||
struct pt_regs *regs, bool wrmsr, bool safe, int reg)
|
||||
{
|
||||
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",
|
||||
(unsigned int)regs->cx, (unsigned int)regs->dx,
|
||||
(unsigned int)regs->ax, regs->ip, (void *)regs->ip))
|
||||
if (__ONCE_LITE_IF(!safe && wrmsr)) {
|
||||
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->ax, regs->ip, (void *)regs->ip);
|
||||
show_stack_regs(regs);
|
||||
}
|
||||
|
||||
if (!safe && !wrmsr &&
|
||||
pr_warn_once("unchecked MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pS)\n",
|
||||
(unsigned int)regs->cx, regs->ip, (void *)regs->ip))
|
||||
if (__ONCE_LITE_IF(!safe && !wrmsr)) {
|
||||
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);
|
||||
show_stack_regs(regs);
|
||||
}
|
||||
|
||||
if (!wrmsr) {
|
||||
/* Pretend that the read succeeded and returned 0. */
|
||||
|
||||
@@ -9,15 +9,27 @@
|
||||
*/
|
||||
#define DO_ONCE_LITE(func, ...) \
|
||||
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; \
|
||||
bool __ret_cond = !!(condition); \
|
||||
bool __ret_once = false; \
|
||||
\
|
||||
if (unlikely(__ret_cond && !__already_done)) { \
|
||||
__already_done = true; \
|
||||
__ret_once = true; \
|
||||
} \
|
||||
unlikely(__ret_once); \
|
||||
})
|
||||
|
||||
#define DO_ONCE_LITE_IF(condition, func, ...) \
|
||||
({ \
|
||||
bool __ret_do_once = !!(condition); \
|
||||
\
|
||||
if (unlikely(__ret_do_once && !__already_done)) { \
|
||||
__already_done = true; \
|
||||
if (__ONCE_LITE_IF(__ret_do_once)) \
|
||||
func(__VA_ARGS__); \
|
||||
} \
|
||||
\
|
||||
unlikely(__ret_do_once); \
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user