Skip to content

Commit

Permalink
x86/returnthunk: Allow different return thunks
Browse files Browse the repository at this point in the history
In preparation for call depth tracking on Intel SKL CPUs, make it possible
to patch in a SKL specific return thunk.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/20220915111147.680469665@infradead.org
  • Loading branch information
Peter Zijlstra committed Oct 17, 2022
1 parent eaf44c8 commit 770ae1b
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 7 deletions.
6 changes: 6 additions & 0 deletions arch/x86/include/asm/nospec-branch.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,12 @@ extern void __x86_return_thunk(void);
extern void zen_untrain_ret(void);
extern void entry_ibpb(void);

#ifdef CONFIG_CALL_THUNKS
extern void (*x86_return_thunk)(void);
#else
#define x86_return_thunk (&__x86_return_thunk)
#endif

#ifdef CONFIG_RETPOLINE

#define GEN(reg) \
Expand Down
17 changes: 13 additions & 4 deletions arch/x86/kernel/alternative.c
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,11 @@ void __init_or_module noinline apply_retpolines(s32 *start, s32 *end)
}

#ifdef CONFIG_RETHUNK

#ifdef CONFIG_CALL_THUNKS
void (*x86_return_thunk)(void) __ro_after_init = &__x86_return_thunk;
#endif

/*
* Rewrite the compiler generated return thunk tail-calls.
*
Expand All @@ -533,14 +538,18 @@ static int patch_return(void *addr, struct insn *insn, u8 *bytes)
{
int i = 0;

if (cpu_feature_enabled(X86_FEATURE_RETHUNK))
return -1;
if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) {
if (x86_return_thunk == __x86_return_thunk)
return -1;

bytes[i++] = RET_INSN_OPCODE;
i = JMP32_INSN_SIZE;
__text_gen_insn(bytes, JMP32_INSN_OPCODE, addr, x86_return_thunk, i);
} else {
bytes[i++] = RET_INSN_OPCODE;
}

for (; i < insn->length;)
bytes[i++] = INT3_INSN_OPCODE;

return i;
}

Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size)

ip = trampoline + size;
if (cpu_feature_enabled(X86_FEATURE_RETHUNK))
__text_gen_insn(ip, JMP32_INSN_OPCODE, ip, &__x86_return_thunk, JMP32_INSN_SIZE);
__text_gen_insn(ip, JMP32_INSN_OPCODE, ip, x86_return_thunk, JMP32_INSN_SIZE);
else
memcpy(ip, retq, sizeof(retq));

Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/static_call.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ static void __ref __static_call_transform(void *insn, enum insn_type type,

case RET:
if (cpu_feature_enabled(X86_FEATURE_RETHUNK))
code = text_gen_insn(JMP32_INSN_OPCODE, insn, &__x86_return_thunk);
code = text_gen_insn(JMP32_INSN_OPCODE, insn, x86_return_thunk);
else
code = &retinsn;
break;
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/net/bpf_jit_comp.c
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ static void emit_return(u8 **pprog, u8 *ip)
u8 *prog = *pprog;

if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) {
emit_jump(&prog, &__x86_return_thunk, ip);
emit_jump(&prog, x86_return_thunk, ip);
} else {
EMIT1(0xC3); /* ret */
if (IS_ENABLED(CONFIG_SLS))
Expand Down

0 comments on commit 770ae1b

Please sign in to comment.