Commit ecf9b7bf authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
Loading
Loading
Loading
Loading
+18 −6
Original line number Diff line number Diff line
@@ -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
+9 −7
Original line number Diff line number Diff line
@@ -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",
	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))
			(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. */
+16 −4
Original line number Diff line number Diff line
@@ -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_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;				\
			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);				\
	})