Skip to content

Commit ab9fea5

Browse files
author
Peter Zijlstra
committed
x86/alternative: Simplify callthunk patching
Now that paravirt call patching is implemented using alternatives, it is possible to avoid having to patch the alternative sites by including the altinstr_replacement calls in the call_sites list. This means we're now stacking relative adjustments like so: callthunks_patch_builtin_calls(): patches all function calls to target: func() -> func()-10 since the CALL accounting lives in the CALL_PADDING. This explicitly includes .altinstr_replacement alt_replace_call(): patches: x86_BUG() -> target() this patching is done in a relative manner, and will preserve the above adjustment, meaning that with calldepth patching it will do: x86_BUG()-10 -> target()-10 apply_relocation(): does code relocation, and adjusts all RIP-relative instructions to the new location, also in a relative manner. Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Reviewed-by: Sami Tolvanen <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 93f16a1 commit ab9fea5

File tree

6 files changed

+13
-39
lines changed

6 files changed

+13
-39
lines changed

arch/x86/include/asm/alternative.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ struct module;
100100

101101
struct callthunk_sites {
102102
s32 *call_start, *call_end;
103-
struct alt_instr *alt_start, *alt_end;
104103
};
105104

106105
#ifdef CONFIG_CALL_THUNKS

arch/x86/kernel/alternative.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1705,14 +1705,14 @@ void __init alternative_instructions(void)
17051705
apply_retpolines(__retpoline_sites, __retpoline_sites_end);
17061706
apply_returns(__return_sites, __return_sites_end);
17071707

1708-
apply_alternatives(__alt_instructions, __alt_instructions_end);
1709-
17101708
/*
1711-
* Now all calls are established. Apply the call thunks if
1712-
* required.
1709+
* Adjust all CALL instructions to point to func()-10, including
1710+
* those in .altinstr_replacement.
17131711
*/
17141712
callthunks_patch_builtin_calls();
17151713

1714+
apply_alternatives(__alt_instructions, __alt_instructions_end);
1715+
17161716
/*
17171717
* Seal all functions that do not have their address taken.
17181718
*/

arch/x86/kernel/callthunks.c

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -239,22 +239,11 @@ patch_call_sites(s32 *start, s32 *end, const struct core_text *ct)
239239
patch_call((void *)s + *s, ct);
240240
}
241241

242-
static __init_or_module void
243-
patch_alt_call_sites(struct alt_instr *start, struct alt_instr *end,
244-
const struct core_text *ct)
245-
{
246-
struct alt_instr *a;
247-
248-
for (a = start; a < end; a++)
249-
patch_call((void *)&a->instr_offset + a->instr_offset, ct);
250-
}
251-
252242
static __init_or_module void
253243
callthunks_setup(struct callthunk_sites *cs, const struct core_text *ct)
254244
{
255245
prdbg("Patching call sites %s\n", ct->name);
256246
patch_call_sites(cs->call_start, cs->call_end, ct);
257-
patch_alt_call_sites(cs->alt_start, cs->alt_end, ct);
258247
prdbg("Patching call sites done%s\n", ct->name);
259248
}
260249

@@ -263,8 +252,6 @@ void __init callthunks_patch_builtin_calls(void)
263252
struct callthunk_sites cs = {
264253
.call_start = __call_sites,
265254
.call_end = __call_sites_end,
266-
.alt_start = __alt_instructions,
267-
.alt_end = __alt_instructions_end
268255
};
269256

270257
if (!cpu_feature_enabled(X86_FEATURE_CALL_DEPTH))

arch/x86/kernel/module.c

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -275,26 +275,21 @@ int module_finalize(const Elf_Ehdr *hdr,
275275
void *rseg = (void *)returns->sh_addr;
276276
apply_returns(rseg, rseg + returns->sh_size);
277277
}
278-
if (alt) {
279-
/* patch .altinstructions */
280-
void *aseg = (void *)alt->sh_addr;
281-
apply_alternatives(aseg, aseg + alt->sh_size);
282-
}
283-
if (calls || alt) {
278+
if (calls) {
284279
struct callthunk_sites cs = {};
285280

286281
if (calls) {
287282
cs.call_start = (void *)calls->sh_addr;
288283
cs.call_end = (void *)calls->sh_addr + calls->sh_size;
289284
}
290285

291-
if (alt) {
292-
cs.alt_start = (void *)alt->sh_addr;
293-
cs.alt_end = (void *)alt->sh_addr + alt->sh_size;
294-
}
295-
296286
callthunks_patch_module_calls(&cs, me);
297287
}
288+
if (alt) {
289+
/* patch .altinstructions */
290+
void *aseg = (void *)alt->sh_addr;
291+
apply_alternatives(aseg, aseg + alt->sh_size);
292+
}
298293
if (ibt_endbr) {
299294
void *iseg = (void *)ibt_endbr->sh_addr;
300295
apply_seal_endbr(iseg, iseg + ibt_endbr->sh_size);

tools/objtool/arch/x86/decode.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,5 +850,6 @@ bool arch_is_rethunk(struct symbol *sym)
850850
bool arch_is_embedded_insn(struct symbol *sym)
851851
{
852852
return !strcmp(sym->name, "retbleed_return_thunk") ||
853+
!strcmp(sym->name, "srso_alias_safe_ret") ||
853854
!strcmp(sym->name, "srso_safe_ret");
854855
}

tools/objtool/check.c

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,15 +1283,6 @@ static void annotate_call_site(struct objtool_file *file,
12831283
if (!sym)
12841284
sym = reloc->sym;
12851285

1286-
/*
1287-
* Alternative replacement code is just template code which is
1288-
* sometimes copied to the original instruction. For now, don't
1289-
* annotate it. (In the future we might consider annotating the
1290-
* original instruction if/when it ever makes sense to do so.)
1291-
*/
1292-
if (!strcmp(insn->sec->name, ".altinstr_replacement"))
1293-
return;
1294-
12951286
if (sym->static_call_tramp) {
12961287
list_add_tail(&insn->call_node, &file->static_call_list);
12971288
return;
@@ -1349,7 +1340,8 @@ static void annotate_call_site(struct objtool_file *file,
13491340
return;
13501341
}
13511342

1352-
if (insn->type == INSN_CALL && !insn->sec->init)
1343+
if (insn->type == INSN_CALL && !insn->sec->init &&
1344+
!insn->_call_dest->embedded_insn)
13531345
list_add_tail(&insn->call_node, &file->call_list);
13541346

13551347
if (!sibling && dead_end_function(file, sym))

0 commit comments

Comments
 (0)