In preparation for the objtool klp diff subcommand, define the entry
size for the .static_call_sites section in its ELF header.  This will
allow tooling to extract individual entries.

Signed-off-by: Josh Poimboeuf <jpoim...@kernel.org>
---
 arch/x86/include/asm/static_call.h      |  3 ++-
 include/linux/static_call.h             |  6 ------
 include/linux/static_call_types.h       |  6 ++++++
 kernel/bounds.c                         |  4 ++++
 tools/include/linux/static_call_types.h |  6 ++++++
 tools/objtool/check.c                   | 11 +++++++++--
 6 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/arch/x86/include/asm/static_call.h 
b/arch/x86/include/asm/static_call.h
index 41502bd2afd6..e03ad9bbbf59 100644
--- a/arch/x86/include/asm/static_call.h
+++ b/arch/x86/include/asm/static_call.h
@@ -58,7 +58,8 @@
        ARCH_DEFINE_STATIC_CALL_TRAMP(name, __static_call_return0)
 
 #define ARCH_ADD_TRAMP_KEY(name)                                       \
-       asm(".pushsection .static_call_tramp_key, \"a\"         \n"     \
+       asm(".pushsection .static_call_tramp_key, \"aM\", @progbits, "  \
+           __stringify(STATIC_CALL_TRAMP_KEY_SIZE) "\n"                \
            ".long " STATIC_CALL_TRAMP_STR(name) " - .          \n"     \
            ".long " STATIC_CALL_KEY_STR(name) " - .            \n"     \
            ".popsection                                        \n")
diff --git a/include/linux/static_call.h b/include/linux/static_call.h
index 78a77a4ae0ea..5210612817f2 100644
--- a/include/linux/static_call.h
+++ b/include/linux/static_call.h
@@ -172,12 +172,6 @@ struct static_call_mod {
        struct static_call_site *sites;
 };
 
-/* For finding the key associated with a trampoline */
-struct static_call_tramp_key {
-       s32 tramp;
-       s32 key;
-};
-
 extern void __static_call_update(struct static_call_key *key, void *tramp, 
void *func);
 extern int static_call_mod_init(struct module *mod);
 extern int static_call_text_reserved(void *start, void *end);
diff --git a/include/linux/static_call_types.h 
b/include/linux/static_call_types.h
index 5a00b8b2cf9f..eb772df625d4 100644
--- a/include/linux/static_call_types.h
+++ b/include/linux/static_call_types.h
@@ -34,6 +34,12 @@ struct static_call_site {
        s32 key;
 };
 
+/* For finding the key associated with a trampoline */
+struct static_call_tramp_key {
+       s32 tramp;
+       s32 key;
+};
+
 #define DECLARE_STATIC_CALL(name, func)                                        
\
        extern struct static_call_key STATIC_CALL_KEY(name);            \
        extern typeof(func) STATIC_CALL_TRAMP(name);
diff --git a/kernel/bounds.c b/kernel/bounds.c
index e4c7ded3dc48..21c37e3ea629 100644
--- a/kernel/bounds.c
+++ b/kernel/bounds.c
@@ -14,6 +14,7 @@
 #include <linux/log2.h>
 #include <linux/spinlock_types.h>
 #include <linux/jump_label.h>
+#include <linux/static_call_types.h>
 
 int main(void)
 {
@@ -33,6 +34,9 @@ int main(void)
 #endif
 #if defined(CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE) && defined(CONFIG_JUMP_LABEL)
        DEFINE(JUMP_ENTRY_SIZE, sizeof(struct jump_entry));
+#endif
+#ifdef CONFIG_HAVE_STATIC_CALL_INLINE
+       DEFINE(STATIC_CALL_TRAMP_KEY_SIZE, sizeof(struct 
static_call_tramp_key));
 #endif
        /* End of constants */
 
diff --git a/tools/include/linux/static_call_types.h 
b/tools/include/linux/static_call_types.h
index 5a00b8b2cf9f..eb772df625d4 100644
--- a/tools/include/linux/static_call_types.h
+++ b/tools/include/linux/static_call_types.h
@@ -34,6 +34,12 @@ struct static_call_site {
        s32 key;
 };
 
+/* For finding the key associated with a trampoline */
+struct static_call_tramp_key {
+       s32 tramp;
+       s32 key;
+};
+
 #define DECLARE_STATIC_CALL(name, func)                                        
\
        extern struct static_call_key STATIC_CALL_KEY(name);            \
        extern typeof(func) STATIC_CALL_TRAMP(name);
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 3afc748ba516..c3e1ca3dba06 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -650,8 +650,15 @@ static int create_static_call_sections(struct objtool_file 
*file)
        if (!sec)
                return -1;
 
-       /* Allow modules to modify the low bits of static_call_site::key */
-       sec->sh.sh_flags |= SHF_WRITE;
+       /*
+        * Set SHF_MERGE to prevent tooling from stripping entsize.
+        *
+        * SHF_WRITE would also get set here to allow modules to modify the low
+        * bits of static_call_site::key, but the LLVM linker doesn't allow
+        * SHF_MERGE+SHF_WRITE for whatever reason.  That gets fixed up by the
+        * makefiles with CONFIG_NEED_MODULE_PERMISSIONS_FIX.
+        */
+       sec->sh.sh_flags |= SHF_MERGE;
 
        idx = 0;
        list_for_each_entry(insn, &file->static_call_list, call_node) {
-- 
2.49.0


Reply via email to