x86/alternative: Optimize returns patching
Borislav Petkov
maintainerPATCH 1/1 x86/alternative: Optimize returns patching
From: "Borislav Petkov (AMD)" <[email protected]>
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.
--- arch/x86/kernel/alternative.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
arch/x86/kernel/alternative.c +10 -3
@@ -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 ; }
@@ -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;
Signature · 1 line
2.35.1
Quoted 10 lines · Borislav Petkov
From: "Borislav Petkov (AMD)" <[email protected]>
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_RETHUNKis 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) <[email protected]>
Quoted 42 lines
--- arch/x86/kernel/alternative.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)arch/x86/kernel/alternative.c +10
-3@@ -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 ; }@@ -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;Signature · 1 line
2.35.1
The following commit has been merged into the x86/alternatives branch of tip:
The following commit has been merged into the x86/alternatives branch of tip:
Commit-ID: d2408e043e7296017420aa5929b3bba4d5e61013 Gitweb: https://git.kernel.org/tip/d2408e043e7296017420aa5929b3bba4d5e61013 Author: Borislav Petkov (AMD) <[email protected]> AuthorDate: Fri, 12 May 2023 14:05:11 +02:00 Committer: Borislav Petkov (AMD) <[email protected]> CommitterDate: Fri, 12 May 2023 17:53:18 +02:00
x86/alternative: Optimize returns patching
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.
--- arch/x86/kernel/alternative.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
arch/x86/kernel/alternative.c +10 -3
@@ -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 ; }
@@ -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;