lkml.org 
[lkml]   [2021]   [Apr]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[tip: x86/core] objtool: Keep track of retpoline call sites
    The following commit has been merged into the x86/core branch of tip:

    Commit-ID: 43d5430ad74ef5156353af7aec352426ec7a8e57
    Gitweb: https://git.kernel.org/tip/43d5430ad74ef5156353af7aec352426ec7a8e57
    Author: Peter Zijlstra <peterz@infradead.org>
    AuthorDate: Fri, 26 Mar 2021 16:12:12 +01:00
    Committer: Ingo Molnar <mingo@kernel.org>
    CommitterDate: Fri, 02 Apr 2021 12:45:27 +02:00

    objtool: Keep track of retpoline call sites

    Provide infrastructure for architectures to rewrite/augment compiler
    generated retpoline calls. Similar to what we do for static_call()s,
    keep track of the instructions that are retpoline calls.

    Use the same list_head, since a retpoline call cannot also be a
    static_call.

    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Signed-off-by: Borislav Petkov <bp@suse.de>
    Signed-off-by: Ingo Molnar <mingo@kernel.org>
    Reviewed-by: Miroslav Benes <mbenes@suse.cz>
    Link: https://lkml.kernel.org/r/20210326151300.130805730@infradead.org
    ---
    tools/objtool/check.c | 34 ++++++++++++++++++++----
    tools/objtool/include/objtool/arch.h | 2 +-
    tools/objtool/include/objtool/check.h | 2 +-
    tools/objtool/include/objtool/objtool.h | 1 +-
    tools/objtool/objtool.c | 1 +-
    5 files changed, 34 insertions(+), 6 deletions(-)

    diff --git a/tools/objtool/check.c b/tools/objtool/check.c
    index 600fa67..77074db 100644
    --- a/tools/objtool/check.c
    +++ b/tools/objtool/check.c
    @@ -451,7 +451,7 @@ static int create_static_call_sections(struct objtool_file *file)
    return 0;

    idx = 0;
    - list_for_each_entry(insn, &file->static_call_list, static_call_node)
    + list_for_each_entry(insn, &file->static_call_list, call_node)
    idx++;

    sec = elf_create_section(file->elf, ".static_call_sites", SHF_WRITE,
    @@ -460,7 +460,7 @@ static int create_static_call_sections(struct objtool_file *file)
    return -1;

    idx = 0;
    - list_for_each_entry(insn, &file->static_call_list, static_call_node) {
    + list_for_each_entry(insn, &file->static_call_list, call_node) {

    site = (struct static_call_site *)sec->data->d_buf + idx;
    memset(site, 0, sizeof(struct static_call_site));
    @@ -829,13 +829,16 @@ static int add_jump_destinations(struct objtool_file *file)
    else
    insn->type = INSN_JUMP_DYNAMIC_CONDITIONAL;

    + list_add_tail(&insn->call_node,
    + &file->retpoline_call_list);
    +
    insn->retpoline_safe = true;
    continue;
    } else if (insn->func) {
    /* internal or external sibling call (with reloc) */
    insn->call_dest = reloc->sym;
    if (insn->call_dest->static_call_tramp) {
    - list_add_tail(&insn->static_call_node,
    + list_add_tail(&insn->call_node,
    &file->static_call_list);
    }
    continue;
    @@ -897,7 +900,7 @@ static int add_jump_destinations(struct objtool_file *file)
    /* internal sibling call (without reloc) */
    insn->call_dest = insn->jump_dest->func;
    if (insn->call_dest->static_call_tramp) {
    - list_add_tail(&insn->static_call_node,
    + list_add_tail(&insn->call_node,
    &file->static_call_list);
    }
    }
    @@ -981,6 +984,9 @@ static int add_call_destinations(struct objtool_file *file)
    insn->type = INSN_CALL_DYNAMIC;
    insn->retpoline_safe = true;

    + list_add_tail(&insn->call_node,
    + &file->retpoline_call_list);
    +
    remove_insn_ops(insn);
    continue;

    @@ -988,7 +994,7 @@ static int add_call_destinations(struct objtool_file *file)
    insn->call_dest = reloc->sym;

    if (insn->call_dest && insn->call_dest->static_call_tramp) {
    - list_add_tail(&insn->static_call_node,
    + list_add_tail(&insn->call_node,
    &file->static_call_list);
    }

    @@ -1714,6 +1720,11 @@ static void mark_rodata(struct objtool_file *file)
    file->rodata = found;
    }

    +__weak int arch_rewrite_retpolines(struct objtool_file *file)
    +{
    + return 0;
    +}
    +
    static int decode_sections(struct objtool_file *file)
    {
    int ret;
    @@ -1742,6 +1753,10 @@ static int decode_sections(struct objtool_file *file)
    if (ret)
    return ret;

    + /*
    + * Must be before add_special_section_alts() as that depends on
    + * jump_dest being set.
    + */
    ret = add_jump_destinations(file);
    if (ret)
    return ret;
    @@ -1778,6 +1793,15 @@ static int decode_sections(struct objtool_file *file)
    if (ret)
    return ret;

    + /*
    + * Must be after add_special_section_alts(), since this will emit
    + * alternatives. Must be after add_{jump,call}_destination(), since
    + * those create the call insn lists.
    + */
    + ret = arch_rewrite_retpolines(file);
    + if (ret)
    + return ret;
    +
    return 0;
    }

    diff --git a/tools/objtool/include/objtool/arch.h b/tools/objtool/include/objtool/arch.h
    index bb30993..48b540a 100644
    --- a/tools/objtool/include/objtool/arch.h
    +++ b/tools/objtool/include/objtool/arch.h
    @@ -88,4 +88,6 @@ int arch_decode_hint_reg(struct instruction *insn, u8 sp_reg);

    bool arch_is_retpoline(struct symbol *sym);

    +int arch_rewrite_retpolines(struct objtool_file *file);
    +
    #endif /* _ARCH_H */
    diff --git a/tools/objtool/include/objtool/check.h b/tools/objtool/include/objtool/check.h
    index f5be798..e5528ce 100644
    --- a/tools/objtool/include/objtool/check.h
    +++ b/tools/objtool/include/objtool/check.h
    @@ -39,7 +39,7 @@ struct alt_group {
    struct instruction {
    struct list_head list;
    struct hlist_node hash;
    - struct list_head static_call_node;
    + struct list_head call_node;
    struct list_head mcount_loc_node;
    struct section *sec;
    unsigned long offset;
    diff --git a/tools/objtool/include/objtool/objtool.h b/tools/objtool/include/objtool/objtool.h
    index e68e374..e4084af 100644
    --- a/tools/objtool/include/objtool/objtool.h
    +++ b/tools/objtool/include/objtool/objtool.h
    @@ -18,6 +18,7 @@ struct objtool_file {
    struct elf *elf;
    struct list_head insn_list;
    DECLARE_HASHTABLE(insn_hash, 20);
    + struct list_head retpoline_call_list;
    struct list_head static_call_list;
    struct list_head mcount_loc_list;
    bool ignore_unreachables, c_file, hints, rodata;
    diff --git a/tools/objtool/objtool.c b/tools/objtool/objtool.c
    index 7b97ce4..3a3ea1b 100644
    --- a/tools/objtool/objtool.c
    +++ b/tools/objtool/objtool.c
    @@ -61,6 +61,7 @@ struct objtool_file *objtool_open_read(const char *_objname)

    INIT_LIST_HEAD(&file.insn_list);
    hash_init(file.insn_hash);
    + INIT_LIST_HEAD(&file.retpoline_call_list);
    INIT_LIST_HEAD(&file.static_call_list);
    INIT_LIST_HEAD(&file.mcount_loc_list);
    file.c_file = !vmlinux && find_section_by_name(file.elf, ".comment");
    \
     
     \ /
      Last update: 2021-04-03 13:12    [W:2.529 / U:2.796 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site