Jiri Slaby 2f5236
From: Peter Zijlstra <peterz@infradead.org>
Jiri Slaby 2f5236
Date: Wed, 8 Feb 2023 18:10:51 +0100
Jiri Slaby 2f5236
Subject: x86/alternative: Make debug-alternative selective
Jiri Slaby 2f5236
Git-commit: 6becb5026b8192e0ed6619d6e7793c2f1288244f
Jiri Slaby 2f5236
Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git#master
Jiri Slaby 2f5236
Patch-mainline: Queued in subsystem maintainer repository
Jiri Slaby 2f5236
References: bsc#1206578
Jiri Slaby 2f5236
Jiri Slaby 2f5236
Using debug-alternative generates a *LOT* of output, extend it a bit
Jiri Slaby 2f5236
to select which of the many rewrites it reports on.
Jiri Slaby 2f5236
Jiri Slaby 2f5236
[js] no IBT, drop the hunk
Jiri Slaby 2f5236
Jiri Slaby 2f5236
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Jiri Slaby 2f5236
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Jiri Slaby 2f5236
Link: https://lore.kernel.org/r/20230208171431.253636689@infradead.org
Jiri Slaby 2f5236
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Jiri Slaby 2f5236
---
Jiri Slaby 2f5236
 arch/x86/kernel/alternative.c |   56 +++++++++++++++++++++++++-----------------
Jiri Slaby 2f5236
 1 file changed, 34 insertions(+), 22 deletions(-)
Jiri Slaby 2f5236
Jiri Slaby 2f5236
--- a/arch/x86/kernel/alternative.c
Jiri Slaby 2f5236
+++ b/arch/x86/kernel/alternative.c
Jiri Slaby 2f5236
@@ -37,11 +37,23 @@ EXPORT_SYMBOL_GPL(alternatives_patched);
Jiri Slaby 2f5236
 
Jiri Slaby 2f5236
 #define MAX_PATCH_LEN (255-1)
Jiri Slaby 2f5236
 
Jiri Slaby 2f5236
-static int __initdata_or_module debug_alternative;
Jiri Slaby 2f5236
+#define DA_ALL		(~0)
Jiri Slaby 2f5236
+#define DA_ALT		0x01
Jiri Slaby 2f5236
+#define DA_RET		0x02
Jiri Slaby 2f5236
+#define DA_RETPOLINE	0x04
Jiri Slaby 2f5236
+#define DA_ENDBR	0x08
Jiri Slaby 2f5236
+#define DA_SMP		0x10
Jiri Slaby 2f5236
+
Jiri Slaby 2f5236
+static unsigned int __initdata_or_module debug_alternative;
Jiri Slaby 2f5236
 
Jiri Slaby 2f5236
 static int __init debug_alt(char *str)
Jiri Slaby 2f5236
 {
Jiri Slaby 2f5236
-	debug_alternative = 1;
Jiri Slaby 2f5236
+	if (str && *str == '=')
Jiri Slaby 2f5236
+		str++;
Jiri Slaby 2f5236
+
Jiri Slaby 2f5236
+	if (!str || kstrtouint(str, 0, &debug_alternative))
Jiri Slaby 2f5236
+		debug_alternative = DA_ALL;
Jiri Slaby 2f5236
+
Jiri Slaby 2f5236
 	return 1;
Jiri Slaby 2f5236
 }
Jiri Slaby 2f5236
 __setup("debug-alternative", debug_alt);
Jiri Slaby 2f5236
@@ -55,15 +67,15 @@ static int __init setup_noreplace_smp(ch
Jiri Slaby 2f5236
 }
Jiri Slaby 2f5236
 __setup("noreplace-smp", setup_noreplace_smp);
Jiri Slaby 2f5236
 
Jiri Slaby 2f5236
-#define DPRINTK(fmt, args...)						\
Jiri Slaby 2f5236
+#define DPRINTK(type, fmt, args...)					\
Jiri Slaby 2f5236
 do {									\
Jiri Slaby 2f5236
-	if (debug_alternative)						\
Jiri Slaby 2f5236
+	if (debug_alternative & DA_##type)				\
Jiri Slaby 2f5236
 		printk(KERN_DEBUG pr_fmt(fmt) "\n", ##args);		\
Jiri Slaby 2f5236
 } while (0)
Jiri Slaby 2f5236
 
Jiri Slaby 2f5236
-#define DUMP_BYTES(buf, len, fmt, args...)				\
Jiri Slaby 2f5236
+#define DUMP_BYTES(type, buf, len, fmt, args...)			\
Jiri Slaby 2f5236
 do {									\
Jiri Slaby 2f5236
-	if (unlikely(debug_alternative)) {				\
Jiri Slaby 2f5236
+	if (unlikely(debug_alternative & DA_##type)) {			\
Jiri Slaby 2f5236
 		int j;							\
Jiri Slaby 2f5236
 									\
Jiri Slaby 2f5236
 		if (!(len))						\
Jiri Slaby 2f5236
@@ -146,7 +158,7 @@ recompute_jump(struct alt_instr *a, u8 *
Jiri Slaby 2f5236
 	tgt_rip  = next_rip + o_dspl;
Jiri Slaby 2f5236
 	n_dspl = tgt_rip - orig_insn;
Jiri Slaby 2f5236
 
Jiri Slaby 2f5236
-	DPRINTK("target RIP: %px, new_displ: 0x%x", tgt_rip, n_dspl);
Jiri Slaby 2f5236
+	DPRINTK(ALT, "target RIP: %px, new_displ: 0x%x", tgt_rip, n_dspl);
Jiri Slaby 2f5236
 
Jiri Slaby 2f5236
 	if (tgt_rip - orig_insn >= 0) {
Jiri Slaby 2f5236
 		if (n_dspl - 2 <= 127)
Jiri Slaby 2f5236
@@ -181,7 +193,7 @@ five_byte_jmp:
Jiri Slaby 2f5236
 
Jiri Slaby 2f5236
 done:
Jiri Slaby 2f5236
 
Jiri Slaby 2f5236
-	DPRINTK("final displ: 0x%08x, JMP 0x%lx",
Jiri Slaby 2f5236
+	DPRINTK(ALT, "final displ: 0x%08x, JMP 0x%lx",
Jiri Slaby 2f5236
 		n_dspl, (unsigned long)orig_insn + n_dspl + repl_len);
Jiri Slaby 2f5236
 }
Jiri Slaby 2f5236
 
Jiri Slaby 2f5236
@@ -215,7 +227,7 @@ static __always_inline int optimize_nops
Jiri Slaby 2f5236
 	add_nops(instr + off, nnops);
Jiri Slaby 2f5236
 	local_irq_restore(flags);
Jiri Slaby 2f5236
 
Jiri Slaby 2f5236
-	DUMP_BYTES(instr, instrlen, "%px: [%d:%d) optimized NOPs: ", instr, off, i);
Jiri Slaby 2f5236
+	DUMP_BYTES(ALT, instr, instrlen, "%px: [%d:%d) optimized NOPs: ", instr, off, i);
Jiri Slaby 2f5236
 
Jiri Slaby 2f5236
 	return nnops;
Jiri Slaby 2f5236
 }
Jiri Slaby 2f5236
@@ -268,7 +280,7 @@ void __init_or_module noinline apply_alt
Jiri Slaby 2f5236
 	u8 *instr, *replacement;
Jiri Slaby 2f5236
 	u8 insn_buff[MAX_PATCH_LEN];
Jiri Slaby 2f5236
 
Jiri Slaby 2f5236
-	DPRINTK("alt table %px, -> %px", start, end);
Jiri Slaby 2f5236
+	DPRINTK(ALT, "alt table %px, -> %px", start, end);
Jiri Slaby 2f5236
 	/*
Jiri Slaby 2f5236
 	 * The scan order should be from start to end. A later scanned
Jiri Slaby 2f5236
 	 * alternative code can overwrite previously scanned alternative code.
Jiri Slaby 2f5236
@@ -297,15 +309,15 @@ void __init_or_module noinline apply_alt
Jiri Slaby 2f5236
 		if (!boot_cpu_has(feature) == !(a->cpuid & ALTINSTR_FLAG_INV))
Jiri Slaby 2f5236
 			goto next;
Jiri Slaby 2f5236
 
Jiri Slaby 2f5236
-		DPRINTK("feat: %s%d*32+%d, old: (%pS (%px) len: %d), repl: (%px, len: %d)",
Jiri Slaby 2f5236
+		DPRINTK(ALT, "feat: %s%d*32+%d, old: (%pS (%px) len: %d), repl: (%px, len: %d)",
Jiri Slaby 2f5236
 			(a->cpuid & ALTINSTR_FLAG_INV) ? "!" : "",
Jiri Slaby 2f5236
 			feature >> 5,
Jiri Slaby 2f5236
 			feature & 0x1f,
Jiri Slaby 2f5236
 			instr, instr, a->instrlen,
Jiri Slaby 2f5236
 			replacement, a->replacementlen);
Jiri Slaby 2f5236
 
Jiri Slaby 2f5236
-		DUMP_BYTES(instr, a->instrlen, "%px:   old_insn: ", instr);
Jiri Slaby 2f5236
-		DUMP_BYTES(replacement, a->replacementlen, "%px:   rpl_insn: ", replacement);
Jiri Slaby 2f5236
+		DUMP_BYTES(ALT, instr, a->instrlen, "%px:   old_insn: ", instr);
Jiri Slaby 2f5236
+		DUMP_BYTES(ALT, replacement, a->replacementlen, "%px:   rpl_insn: ", replacement);
Jiri Slaby 2f5236
 
Jiri Slaby 2f5236
 		memcpy(insn_buff, replacement, a->replacementlen);
Jiri Slaby 2f5236
 		insn_buff_sz = a->replacementlen;
Jiri Slaby 2f5236
@@ -318,7 +330,7 @@ void __init_or_module noinline apply_alt
Jiri Slaby 2f5236
 		 */
Jiri Slaby 2f5236
 		if (a->replacementlen == 5 && *insn_buff == 0xe8) {
Jiri Slaby 2f5236
 			*(s32 *)(insn_buff + 1) += replacement - instr;
Jiri Slaby 2f5236
-			DPRINTK("Fix CALL offset: 0x%x, CALL 0x%lx",
Jiri Slaby 2f5236
+			DPRINTK(ALT, "Fix CALL offset: 0x%x, CALL 0x%lx",
Jiri Slaby 2f5236
 				*(s32 *)(insn_buff + 1),
Jiri Slaby 2f5236
 				(unsigned long)instr + *(s32 *)(insn_buff + 1) + 5);
Jiri Slaby 2f5236
 		}
Jiri Slaby 2f5236
@@ -329,7 +341,7 @@ void __init_or_module noinline apply_alt
Jiri Slaby 2f5236
 		for (; insn_buff_sz < a->instrlen; insn_buff_sz++)
Jiri Slaby 2f5236
 			insn_buff[insn_buff_sz] = 0x90;
Jiri Slaby 2f5236
 
Jiri Slaby 2f5236
-		DUMP_BYTES(insn_buff, insn_buff_sz, "%px: final_insn: ", instr);
Jiri Slaby 2f5236
+		DUMP_BYTES(ALT, insn_buff, insn_buff_sz, "%px: final_insn: ", instr);
Jiri Slaby 2f5236
 
Jiri Slaby 2f5236
 		text_poke_early(instr, insn_buff, insn_buff_sz);
Jiri Slaby 2f5236
 
Jiri Slaby 2f5236
@@ -493,15 +505,15 @@ void __init_or_module noinline apply_ret
Jiri Slaby 2f5236
 			continue;
Jiri Slaby 2f5236
 		}
Jiri Slaby 2f5236
 
Jiri Slaby 2f5236
-		DPRINTK("retpoline at: %pS (%px) len: %d to: %pS",
Jiri Slaby 2f5236
+		DPRINTK(RETPOLINE, "retpoline at: %pS (%px) len: %d to: %pS",
Jiri Slaby 2f5236
 			addr, addr, insn.length,
Jiri Slaby 2f5236
 			addr + insn.length + insn.immediate.value);
Jiri Slaby 2f5236
 
Jiri Slaby 2f5236
 		len = patch_retpoline(addr, &insn, bytes);
Jiri Slaby 2f5236
 		if (len == insn.length) {
Jiri Slaby 2f5236
 			optimize_nops(bytes, len);
Jiri Slaby 2f5236
-			DUMP_BYTES(((u8*)addr),  len, "%px: orig: ", addr);
Jiri Slaby 2f5236
-			DUMP_BYTES(((u8*)bytes), len, "%px: repl: ", addr);
Jiri Slaby 2f5236
+			DUMP_BYTES(RETPOLINE, ((u8*)addr),  len, "%px: orig: ", addr);
Jiri Slaby 2f5236
+			DUMP_BYTES(RETPOLINE, ((u8*)bytes), len, "%px: repl: ", addr);
Jiri Slaby 2f5236
 			text_poke_early(addr, bytes, len);
Jiri Slaby 2f5236
 		}
Jiri Slaby 2f5236
 	}
Jiri Slaby 2f5236
@@ -558,14 +570,14 @@ void __init_or_module noinline apply_ret
Jiri Slaby 2f5236
 			      addr, dest, 5, addr))
Jiri Slaby 2f5236
 			continue;
Jiri Slaby 2f5236
 
Jiri Slaby 2f5236
-		DPRINTK("return thunk at: %pS (%px) len: %d to: %pS",
Jiri Slaby 2f5236
+		DPRINTK(RET, "return thunk at: %pS (%px) len: %d to: %pS",
Jiri Slaby 2f5236
 			addr, addr, insn.length,
Jiri Slaby 2f5236
 			addr + insn.length + insn.immediate.value);
Jiri Slaby 2f5236
 
Jiri Slaby 2f5236
 		len = patch_return(addr, &insn, bytes);
Jiri Slaby 2f5236
 		if (len == insn.length) {
Jiri Slaby 2f5236
-			DUMP_BYTES(((u8*)addr),  len, "%px: orig: ", addr);
Jiri Slaby 2f5236
-			DUMP_BYTES(((u8*)bytes), len, "%px: repl: ", addr);
Jiri Slaby 2f5236
+			DUMP_BYTES(RET, ((u8*)addr),  len, "%px: orig: ", addr);
Jiri Slaby 2f5236
+			DUMP_BYTES(RET, ((u8*)bytes), len, "%px: repl: ", addr);
Jiri Slaby 2f5236
 			text_poke_early(addr, bytes, len);
Jiri Slaby 2f5236
 		}
Jiri Slaby 2f5236
 	}
Jiri Slaby 2f5236
@@ -654,7 +666,7 @@ void __init_or_module alternatives_smp_m
Jiri Slaby 2f5236
 	smp->locks_end	= locks_end;
Jiri Slaby 2f5236
 	smp->text	= text;
Jiri Slaby 2f5236
 	smp->text_end	= text_end;
Jiri Slaby 2f5236
-	DPRINTK("locks %p -> %p, text %p -> %p, name %s\n",
Jiri Slaby 2f5236
+	DPRINTK(SMP, "locks %p -> %p, text %p -> %p, name %s\n",
Jiri Slaby 2f5236
 		smp->locks, smp->locks_end,
Jiri Slaby 2f5236
 		smp->text, smp->text_end, smp->name);
Jiri Slaby 2f5236