Skip to content

Commit 6becb50

Browse files
Peter Zijlstrabp3tk0v
authored andcommitted
x86/alternative: Make debug-alternative selective
Using debug-alternative generates a *LOT* of output, extend it a bit to select which of the many rewrites it reports on. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> Link: https://lore.kernel.org/r/20230208171431.253636689@infradead.org
1 parent ac9a786 commit 6becb50

File tree

1 file changed

+37
-25
lines changed

1 file changed

+37
-25
lines changed

arch/x86/kernel/alternative.c

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,23 @@ EXPORT_SYMBOL_GPL(alternatives_patched);
3737

3838
#define MAX_PATCH_LEN (255-1)
3939

40-
static int __initdata_or_module debug_alternative;
40+
#define DA_ALL (~0)
41+
#define DA_ALT 0x01
42+
#define DA_RET 0x02
43+
#define DA_RETPOLINE 0x04
44+
#define DA_ENDBR 0x08
45+
#define DA_SMP 0x10
46+
47+
static unsigned int __initdata_or_module debug_alternative;
4148

4249
static int __init debug_alt(char *str)
4350
{
44-
debug_alternative = 1;
51+
if (str && *str == '=')
52+
str++;
53+
54+
if (!str || kstrtouint(str, 0, &debug_alternative))
55+
debug_alternative = DA_ALL;
56+
4557
return 1;
4658
}
4759
__setup("debug-alternative", debug_alt);
@@ -55,15 +67,15 @@ static int __init setup_noreplace_smp(char *str)
5567
}
5668
__setup("noreplace-smp", setup_noreplace_smp);
5769

58-
#define DPRINTK(fmt, args...) \
70+
#define DPRINTK(type, fmt, args...) \
5971
do { \
60-
if (debug_alternative) \
72+
if (debug_alternative & DA_##type) \
6173
printk(KERN_DEBUG pr_fmt(fmt) "\n", ##args); \
6274
} while (0)
6375

64-
#define DUMP_BYTES(buf, len, fmt, args...) \
76+
#define DUMP_BYTES(type, buf, len, fmt, args...) \
6577
do { \
66-
if (unlikely(debug_alternative)) { \
78+
if (unlikely(debug_alternative & DA_##type)) { \
6779
int j; \
6880
\
6981
if (!(len)) \
@@ -148,7 +160,7 @@ recompute_jump(struct alt_instr *a, u8 *orig_insn, u8 *repl_insn, u8 *insn_buff)
148160
tgt_rip = next_rip + o_dspl;
149161
n_dspl = tgt_rip - orig_insn;
150162

151-
DPRINTK("target RIP: %px, new_displ: 0x%x", tgt_rip, n_dspl);
163+
DPRINTK(ALT, "target RIP: %px, new_displ: 0x%x", tgt_rip, n_dspl);
152164

153165
if (tgt_rip - orig_insn >= 0) {
154166
if (n_dspl - 2 <= 127)
@@ -183,7 +195,7 @@ recompute_jump(struct alt_instr *a, u8 *orig_insn, u8 *repl_insn, u8 *insn_buff)
183195

184196
done:
185197

186-
DPRINTK("final displ: 0x%08x, JMP 0x%lx",
198+
DPRINTK(ALT, "final displ: 0x%08x, JMP 0x%lx",
187199
n_dspl, (unsigned long)orig_insn + n_dspl + repl_len);
188200
}
189201

@@ -217,7 +229,7 @@ static __always_inline int optimize_nops_range(u8 *instr, u8 instrlen, int off)
217229
add_nops(instr + off, nnops);
218230
local_irq_restore(flags);
219231

220-
DUMP_BYTES(instr, instrlen, "%px: [%d:%d) optimized NOPs: ", instr, off, i);
232+
DUMP_BYTES(ALT, instr, instrlen, "%px: [%d:%d) optimized NOPs: ", instr, off, i);
221233

222234
return nnops;
223235
}
@@ -270,7 +282,7 @@ void __init_or_module noinline apply_alternatives(struct alt_instr *start,
270282
u8 *instr, *replacement;
271283
u8 insn_buff[MAX_PATCH_LEN];
272284

273-
DPRINTK("alt table %px, -> %px", start, end);
285+
DPRINTK(ALT, "alt table %px, -> %px", start, end);
274286
/*
275287
* The scan order should be from start to end. A later scanned
276288
* alternative code can overwrite previously scanned alternative code.
@@ -297,15 +309,15 @@ void __init_or_module noinline apply_alternatives(struct alt_instr *start,
297309
if (!boot_cpu_has(a->cpuid) == !(a->flags & ALT_FLAG_NOT))
298310
goto next;
299311

300-
DPRINTK("feat: %s%d*32+%d, old: (%pS (%px) len: %d), repl: (%px, len: %d)",
312+
DPRINTK(ALT, "feat: %s%d*32+%d, old: (%pS (%px) len: %d), repl: (%px, len: %d)",
301313
(a->flags & ALT_FLAG_NOT) ? "!" : "",
302314
a->cpuid >> 5,
303315
a->cpuid & 0x1f,
304316
instr, instr, a->instrlen,
305317
replacement, a->replacementlen);
306318

307-
DUMP_BYTES(instr, a->instrlen, "%px: old_insn: ", instr);
308-
DUMP_BYTES(replacement, a->replacementlen, "%px: rpl_insn: ", replacement);
319+
DUMP_BYTES(ALT, instr, a->instrlen, "%px: old_insn: ", instr);
320+
DUMP_BYTES(ALT, replacement, a->replacementlen, "%px: rpl_insn: ", replacement);
309321

310322
memcpy(insn_buff, replacement, a->replacementlen);
311323
insn_buff_sz = a->replacementlen;
@@ -318,7 +330,7 @@ void __init_or_module noinline apply_alternatives(struct alt_instr *start,
318330
*/
319331
if (a->replacementlen == 5 && *insn_buff == 0xe8) {
320332
*(s32 *)(insn_buff + 1) += replacement - instr;
321-
DPRINTK("Fix CALL offset: 0x%x, CALL 0x%lx",
333+
DPRINTK(ALT, "Fix CALL offset: 0x%x, CALL 0x%lx",
322334
*(s32 *)(insn_buff + 1),
323335
(unsigned long)instr + *(s32 *)(insn_buff + 1) + 5);
324336
}
@@ -329,7 +341,7 @@ void __init_or_module noinline apply_alternatives(struct alt_instr *start,
329341
for (; insn_buff_sz < a->instrlen; insn_buff_sz++)
330342
insn_buff[insn_buff_sz] = 0x90;
331343

332-
DUMP_BYTES(insn_buff, insn_buff_sz, "%px: final_insn: ", instr);
344+
DUMP_BYTES(ALT, insn_buff, insn_buff_sz, "%px: final_insn: ", instr);
333345

334346
text_poke_early(instr, insn_buff, insn_buff_sz);
335347

@@ -555,15 +567,15 @@ void __init_or_module noinline apply_retpolines(s32 *start, s32 *end)
555567
continue;
556568
}
557569

558-
DPRINTK("retpoline at: %pS (%px) len: %d to: %pS",
570+
DPRINTK(RETPOLINE, "retpoline at: %pS (%px) len: %d to: %pS",
559571
addr, addr, insn.length,
560572
addr + insn.length + insn.immediate.value);
561573

562574
len = patch_retpoline(addr, &insn, bytes);
563575
if (len == insn.length) {
564576
optimize_nops(bytes, len);
565-
DUMP_BYTES(((u8*)addr), len, "%px: orig: ", addr);
566-
DUMP_BYTES(((u8*)bytes), len, "%px: repl: ", addr);
577+
DUMP_BYTES(RETPOLINE, ((u8*)addr), len, "%px: orig: ", addr);
578+
DUMP_BYTES(RETPOLINE, ((u8*)bytes), len, "%px: repl: ", addr);
567579
text_poke_early(addr, bytes, len);
568580
}
569581
}
@@ -630,14 +642,14 @@ void __init_or_module noinline apply_returns(s32 *start, s32 *end)
630642
addr, dest, 5, addr))
631643
continue;
632644

633-
DPRINTK("return thunk at: %pS (%px) len: %d to: %pS",
645+
DPRINTK(RET, "return thunk at: %pS (%px) len: %d to: %pS",
634646
addr, addr, insn.length,
635647
addr + insn.length + insn.immediate.value);
636648

637649
len = patch_return(addr, &insn, bytes);
638650
if (len == insn.length) {
639-
DUMP_BYTES(((u8*)addr), len, "%px: orig: ", addr);
640-
DUMP_BYTES(((u8*)bytes), len, "%px: repl: ", addr);
651+
DUMP_BYTES(RET, ((u8*)addr), len, "%px: orig: ", addr);
652+
DUMP_BYTES(RET, ((u8*)bytes), len, "%px: repl: ", addr);
641653
text_poke_early(addr, bytes, len);
642654
}
643655
}
@@ -667,13 +679,13 @@ static void poison_endbr(void *addr, bool warn)
667679
return;
668680
}
669681

670-
DPRINTK("ENDBR at: %pS (%px)", addr, addr);
682+
DPRINTK(ENDBR, "ENDBR at: %pS (%px)", addr, addr);
671683

672684
/*
673685
* When we have IBT, the lack of ENDBR will trigger #CP
674686
*/
675-
DUMP_BYTES(((u8*)addr), 4, "%px: orig: ", addr);
676-
DUMP_BYTES(((u8*)&poison), 4, "%px: repl: ", addr);
687+
DUMP_BYTES(ENDBR, ((u8*)addr), 4, "%px: orig: ", addr);
688+
DUMP_BYTES(ENDBR, ((u8*)&poison), 4, "%px: repl: ", addr);
677689
text_poke_early(addr, &poison, 4);
678690
}
679691

@@ -1148,7 +1160,7 @@ void __init_or_module alternatives_smp_module_add(struct module *mod,
11481160
smp->locks_end = locks_end;
11491161
smp->text = text;
11501162
smp->text_end = text_end;
1151-
DPRINTK("locks %p -> %p, text %p -> %p, name %s\n",
1163+
DPRINTK(SMP, "locks %p -> %p, text %p -> %p, name %s\n",
11521164
smp->locks, smp->locks_end,
11531165
smp->text, smp->text_end, smp->name);
11541166

0 commit comments

Comments
 (0)