Skip to content

Commit

Permalink
x86/alternative: Optimize returns patching
Browse files Browse the repository at this point in the history
Instead of decoding each instruction in the return sites range only to
realize that that return site is a jump to the default return thunk
which is needed - X86_FEATURE_RETHUNK is enabled - lift that check
before the loop and get rid of that loop overhead.

Add comments about what gets patched, while at it.

Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/20230512120952.7924-1-bp@alien8.de
  • Loading branch information
bp3tk0v committed May 12, 2023
1 parent b6c881b commit d2408e0
Showing 1 changed file with 10 additions and 3 deletions.
13 changes: 10 additions & 3 deletions arch/x86/kernel/alternative.c
Original file line number Diff line number Diff line change
Expand Up @@ -693,13 +693,12 @@ static int patch_return(void *addr, struct insn *insn, u8 *bytes)
{
int i = 0;

/* Patch the custom return thunks... */
if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) {
if (x86_return_thunk == __x86_return_thunk)
return -1;

i = JMP32_INSN_SIZE;
__text_gen_insn(bytes, JMP32_INSN_OPCODE, addr, x86_return_thunk, i);
} else {
/* ... or patch them out if not needed. */
bytes[i++] = RET_INSN_OPCODE;
}

Expand All @@ -712,6 +711,14 @@ void __init_or_module noinline apply_returns(s32 *start, s32 *end)
{
s32 *s;

/*
* Do not patch out the default return thunks if those needed are the
* ones generated by the compiler.
*/
if (cpu_feature_enabled(X86_FEATURE_RETHUNK) &&
(x86_return_thunk == __x86_return_thunk))
return;

for (s = start; s < end; s++) {
void *dest = NULL, *addr = (void *)s + *s;
struct insn insn;
Expand Down

0 comments on commit d2408e0

Please sign in to comment.