Add a type field to the alternative description. For now this will be used to annotate static_cpu_has() but possible future uses include using it to implement alternative alignment and special NOP handling. Suggested-by: Borislav Petkov Reviewed-by: Borislav Petkov Signed-off-by: Peter Zijlstra (Intel) --- arch/x86/include/asm/alternative-asm.h | 3 ++- arch/x86/include/asm/alternative.h | 6 +++++- arch/x86/include/asm/cpufeature.h | 2 ++ arch/x86/kernel/alternative.c | 4 ++-- tools/objtool/special.c | 2 +- 5 files changed, 12 insertions(+), 5 deletions(-) --- a/arch/x86/include/asm/alternative-asm.h +++ b/arch/x86/include/asm/alternative-asm.h @@ -25,13 +25,14 @@ * enough information for the alternatives patching code to patch an * instruction. See apply_alternatives(). */ -.macro altinstruction_entry orig alt feature orig_len alt_len pad_len +.macro altinstruction_entry orig alt feature orig_len alt_len pad_len type=0 .long \orig - . .long \alt - . .word \feature .byte \orig_len .byte \alt_len .byte \pad_len + .byte \type .endm /* --- a/arch/x86/include/asm/alternative.h +++ b/arch/x86/include/asm/alternative.h @@ -45,6 +45,8 @@ #define LOCK_PREFIX "" #endif +#define ALT_TYPE_DEFAULT 0 + struct alt_instr { s32 instr_offset; /* original instruction */ s32 repl_offset; /* offset to replacement instruction */ @@ -52,6 +54,7 @@ struct alt_instr { u8 instrlen; /* length of original instruction */ u8 replacementlen; /* length of new instruction */ u8 padlen; /* length of build-time padding */ + u8 type; /* type of alternative */ } __packed; /* @@ -127,7 +130,8 @@ static inline int alternatives_text_rese " .word " __stringify(feature) "\n" /* feature bit */ \ " .byte " alt_total_slen "\n" /* source len */ \ " .byte " alt_rlen(num) "\n" /* replacement len */ \ - " .byte " alt_pad_len "\n" /* pad len */ + " .byte " alt_pad_len "\n" /* pad len */ \ + " .byte 0 \n" /* type */ #define ALTINSTR_REPLACEMENT(newinstr, feature, num) /* replacement */ \ b_replacement(num)":\n\t" newinstr "\n" e_replacement(num) ":\n\t" --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -157,6 +157,7 @@ static __always_inline __pure bool _stat " .byte 3b - 1b\n" /* src len */ " .byte 5f - 4f\n" /* repl len */ " .byte 3b - 2b\n" /* pad len */ + " .byte 0\n" /* type */ ".previous\n" ".section .altinstr_replacement,\"ax\"\n" "4: jmp %l[t_no]\n" @@ -169,6 +170,7 @@ static __always_inline __pure bool _stat " .byte 3b - 1b\n" /* src len */ " .byte 0\n" /* repl len */ " .byte 0\n" /* pad len */ + " .byte 0\n" /* type */ ".previous\n" ".section .altinstr_aux,\"ax\"\n" "6:\n" --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -400,11 +400,11 @@ void __init_or_module noinline apply_alt continue; } - DPRINTK("feat: %d*32+%d, old: (%p, len: %d), repl: (%p, len: %d), pad: %d", + DPRINTK("feat: %d*32+%d, old: (%p, len: %d), repl: (%p, len: %d), pad: %d, type: %d", a->cpuid >> 5, a->cpuid & 0x1f, instr, a->instrlen, - replacement, a->replacementlen, a->padlen); + replacement, a->replacementlen, a->padlen, a->type); DUMP_BYTES(instr, a->instrlen, "%p: old_insn: ", instr); DUMP_BYTES(replacement, a->replacementlen, "%p: rpl_insn: ", replacement); --- a/tools/objtool/special.c +++ b/tools/objtool/special.c @@ -34,7 +34,7 @@ #define JUMP_ORIG_OFFSET 0 #define JUMP_NEW_OFFSET 8 -#define ALT_ENTRY_SIZE 13 +#define ALT_ENTRY_SIZE 14 #define ALT_ORIG_OFFSET 0 #define ALT_NEW_OFFSET 4 #define ALT_FEATURE_OFFSET 8