To avoid duplication of inline asm between C and Rust, we need to
import the inline asm from the relevant `jump_label.h` header into Rust.
To make that easier, this patch updates the header files to expose the
inline asm via a new ARCH_STATIC_BRANCH_ASM macro.

The header files are all updated to define a ARCH_STATIC_BRANCH_ASM that
takes the same arguments in a consistent order so that Rust can use the
same logic for every architecture.

Suggested-by: Peter Zijlstra (Intel) <pet...@infradead.org>
Co-developed-by: Miguel Ojeda <oj...@kernel.org>
Signed-off-by: Miguel Ojeda <oj...@kernel.org>
Acked-by: Peter Zijlstra (Intel) <pet...@infradead.org>
Acked-by: Catalin Marinas <catalin.mari...@arm.com>
Acked-by: Palmer Dabbelt <pal...@rivosinc.com> # RISC-V
Signed-off-by: Alice Ryhl <alicer...@google.com>
---
 arch/arm/include/asm/jump_label.h       | 14 +++++----
 arch/arm64/include/asm/jump_label.h     | 20 ++++++++-----
 arch/loongarch/include/asm/jump_label.h | 16 +++++++----
 arch/riscv/include/asm/jump_label.h     | 50 ++++++++++++++++++---------------
 arch/x86/include/asm/jump_label.h       | 35 +++++++++--------------
 5 files changed, 73 insertions(+), 62 deletions(-)

diff --git a/arch/arm/include/asm/jump_label.h 
b/arch/arm/include/asm/jump_label.h
index e4eb54f6cd9f..a35aba7f548c 100644
--- a/arch/arm/include/asm/jump_label.h
+++ b/arch/arm/include/asm/jump_label.h
@@ -9,13 +9,17 @@
 
 #define JUMP_LABEL_NOP_SIZE 4
 
+/* This macro is also expanded on the Rust side. */
+#define ARCH_STATIC_BRANCH_ASM(key, label)             \
+       "1:\n\t"                                        \
+       WASM(nop) "\n\t"                                \
+       ".pushsection __jump_table,  \"aw\"\n\t"        \
+       ".word 1b, " label ", " key "\n\t"              \
+       ".popsection\n\t"                               \
+
 static __always_inline bool arch_static_branch(struct static_key *key, bool 
branch)
 {
-       asm goto("1:\n\t"
-                WASM(nop) "\n\t"
-                ".pushsection __jump_table,  \"aw\"\n\t"
-                ".word 1b, %l[l_yes], %c0\n\t"
-                ".popsection\n\t"
+       asm goto(ARCH_STATIC_BRANCH_ASM("%c0", "%l[l_yes]")
                 : :  "i" (&((char *)key)[branch]) :  : l_yes);
 
        return false;
diff --git a/arch/arm64/include/asm/jump_label.h 
b/arch/arm64/include/asm/jump_label.h
index a0a5bbae7229..424ed421cd97 100644
--- a/arch/arm64/include/asm/jump_label.h
+++ b/arch/arm64/include/asm/jump_label.h
@@ -19,10 +19,14 @@
 #define JUMP_TABLE_ENTRY(key, label)                   \
        ".pushsection   __jump_table, \"aw\"\n\t"       \
        ".align         3\n\t"                          \
-       ".long          1b - ., %l["#label"] - .\n\t"   \
-       ".quad          %c0 - .\n\t"                    \
-       ".popsection\n\t"                               \
-       :  :  "i"(key) :  : label
+       ".long          1b - ., " label " - .\n\t"      \
+       ".quad          " key " - .\n\t"                \
+       ".popsection\n\t"
+
+/* This macro is also expanded on the Rust side. */
+#define ARCH_STATIC_BRANCH_ASM(key, label)             \
+       "1:     nop\n\t"                                \
+       JUMP_TABLE_ENTRY(key, label)
 
 static __always_inline bool arch_static_branch(struct static_key * const key,
                                               const bool branch)
@@ -30,8 +34,8 @@ static __always_inline bool arch_static_branch(struct 
static_key * const key,
        char *k = &((char *)key)[branch];
 
        asm goto(
-               "1:     nop                                     \n\t"
-               JUMP_TABLE_ENTRY(k, l_yes)
+               ARCH_STATIC_BRANCH_ASM("%c0", "%l[l_yes]")
+               :  :  "i"(k) :  : l_yes
                );
 
        return false;
@@ -43,9 +47,11 @@ static __always_inline bool arch_static_branch_jump(struct 
static_key * const ke
                                                    const bool branch)
 {
        char *k = &((char *)key)[branch];
+
        asm goto(
                "1:     b               %l[l_yes]               \n\t"
-               JUMP_TABLE_ENTRY(k, l_yes)
+               JUMP_TABLE_ENTRY("%c0", "%l[l_yes]")
+               :  :  "i"(k) :  : l_yes
                );
        return false;
 l_yes:
diff --git a/arch/loongarch/include/asm/jump_label.h 
b/arch/loongarch/include/asm/jump_label.h
index 29acfe3de3fa..8a924bd69d19 100644
--- a/arch/loongarch/include/asm/jump_label.h
+++ b/arch/loongarch/include/asm/jump_label.h
@@ -13,18 +13,22 @@
 
 #define JUMP_LABEL_NOP_SIZE    4
 
-#define JUMP_TABLE_ENTRY                               \
+/* This macro is also expanded on the Rust side. */
+#define JUMP_TABLE_ENTRY(key, label)                   \
         ".pushsection  __jump_table, \"aw\"    \n\t"   \
         ".align        3                       \n\t"   \
-        ".long         1b - ., %l[l_yes] - .   \n\t"   \
-        ".quad         %0 - .                  \n\t"   \
+        ".long         1b - ., " label " - .   \n\t"   \
+        ".quad         " key " - .             \n\t"   \
         ".popsection                           \n\t"
 
+#define ARCH_STATIC_BRANCH_ASM(key, label)             \
+       "1:     nop                             \n\t"   \
+       JUMP_TABLE_ENTRY(key, label)
+
 static __always_inline bool arch_static_branch(struct static_key * const key, 
const bool branch)
 {
        asm goto(
-               "1:     nop                     \n\t"
-               JUMP_TABLE_ENTRY
+               ARCH_STATIC_BRANCH_ASM("%0", "%l[l_yes]")
                :  :  "i"(&((char *)key)[branch]) :  : l_yes);
 
        return false;
@@ -37,7 +41,7 @@ static __always_inline bool arch_static_branch_jump(struct 
static_key * const ke
 {
        asm goto(
                "1:     b       %l[l_yes]       \n\t"
-               JUMP_TABLE_ENTRY
+               JUMP_TABLE_ENTRY("%0", "%l[l_yes]")
                :  :  "i"(&((char *)key)[branch]) :  : l_yes);
 
        return false;
diff --git a/arch/riscv/include/asm/jump_label.h 
b/arch/riscv/include/asm/jump_label.h
index 1c768d02bd0c..87a71cc6d146 100644
--- a/arch/riscv/include/asm/jump_label.h
+++ b/arch/riscv/include/asm/jump_label.h
@@ -16,21 +16,28 @@
 
 #define JUMP_LABEL_NOP_SIZE 4
 
+#define JUMP_TABLE_ENTRY(key, label)                   \
+       ".pushsection   __jump_table, \"aw\"    \n\t"   \
+       ".align         " RISCV_LGPTR "         \n\t"   \
+       ".long          1b - ., " label " - .   \n\t"   \
+       "" RISCV_PTR "  " key " - .             \n\t"   \
+       ".popsection                            \n\t"
+
+/* This macro is also expanded on the Rust side. */
+#define ARCH_STATIC_BRANCH_ASM(key, label)             \
+       "       .align          2               \n\t"   \
+       "       .option push                    \n\t"   \
+       "       .option norelax                 \n\t"   \
+       "       .option norvc                   \n\t"   \
+       "1:     nop                             \n\t"   \
+       "       .option pop                     \n\t"   \
+       JUMP_TABLE_ENTRY(key, label)
+
 static __always_inline bool arch_static_branch(struct static_key * const key,
                                               const bool branch)
 {
        asm goto(
-               "       .align          2                       \n\t"
-               "       .option push                            \n\t"
-               "       .option norelax                         \n\t"
-               "       .option norvc                           \n\t"
-               "1:     nop                                     \n\t"
-               "       .option pop                             \n\t"
-               "       .pushsection    __jump_table, \"aw\"    \n\t"
-               "       .align          " RISCV_LGPTR "         \n\t"
-               "       .long           1b - ., %l[label] - .   \n\t"
-               "       " RISCV_PTR "   %0 - .                  \n\t"
-               "       .popsection                             \n\t"
+               ARCH_STATIC_BRANCH_ASM("%0", "%l[label]")
                :  :  "i"(&((char *)key)[branch]) :  : label);
 
        return false;
@@ -38,21 +45,20 @@ static __always_inline bool arch_static_branch(struct 
static_key * const key,
        return true;
 }
 
+#define ARCH_STATIC_BRANCH_JUMP_ASM(key, label)                \
+       "       .align          2               \n\t"   \
+       "       .option push                    \n\t"   \
+       "       .option norelax                 \n\t"   \
+       "       .option norvc                   \n\t"   \
+       "1:     j       " label "               \n\t" \
+       "       .option pop                     \n\t"   \
+       JUMP_TABLE_ENTRY(key, label)
+
 static __always_inline bool arch_static_branch_jump(struct static_key * const 
key,
                                                    const bool branch)
 {
        asm goto(
-               "       .align          2                       \n\t"
-               "       .option push                            \n\t"
-               "       .option norelax                         \n\t"
-               "       .option norvc                           \n\t"
-               "1:     j               %l[label]               \n\t"
-               "       .option pop                             \n\t"
-               "       .pushsection    __jump_table, \"aw\"    \n\t"
-               "       .align          " RISCV_LGPTR "         \n\t"
-               "       .long           1b - ., %l[label] - .   \n\t"
-               "       " RISCV_PTR "   %0 - .                  \n\t"
-               "       .popsection                             \n\t"
+               ARCH_STATIC_BRANCH_JUMP_ASM("%0", "%l[label]")
                :  :  "i"(&((char *)key)[branch]) :  : label);
 
        return false;
diff --git a/arch/x86/include/asm/jump_label.h 
b/arch/x86/include/asm/jump_label.h
index cbbef32517f0..3f1c1d6c0da1 100644
--- a/arch/x86/include/asm/jump_label.h
+++ b/arch/x86/include/asm/jump_label.h
@@ -12,35 +12,28 @@
 #include <linux/stringify.h>
 #include <linux/types.h>
 
-#define JUMP_TABLE_ENTRY                               \
+#define JUMP_TABLE_ENTRY(key, label)                   \
        ".pushsection __jump_table,  \"aw\" \n\t"       \
        _ASM_ALIGN "\n\t"                               \
        ".long 1b - . \n\t"                             \
-       ".long %l[l_yes] - . \n\t"                      \
-       _ASM_PTR "%c0 + %c1 - .\n\t"                    \
+       ".long " label " - . \n\t"                      \
+       _ASM_PTR " " key " - . \n\t"                    \
        ".popsection \n\t"
 
+/* This macro is also expanded on the Rust side. */
 #ifdef CONFIG_HAVE_JUMP_LABEL_HACK
-
-static __always_inline bool arch_static_branch(struct static_key *key, bool 
branch)
-{
-       asm goto("1:"
-               "jmp %l[l_yes] # objtool NOPs this \n\t"
-               JUMP_TABLE_ENTRY
-               : :  "i" (key), "i" (2 | branch) : : l_yes);
-
-       return false;
-l_yes:
-       return true;
-}
-
+#define ARCH_STATIC_BRANCH_ASM(key, label)             \
+       "1: jmp " label " # objtool NOPs this \n\t"     \
+       JUMP_TABLE_ENTRY(key " + 2", label)
 #else /* !CONFIG_HAVE_JUMP_LABEL_HACK */
+#define ARCH_STATIC_BRANCH_ASM(key, label)             \
+       "1: .byte " __stringify(BYTES_NOP5) "\n\t"      \
+       JUMP_TABLE_ENTRY(key, label)
+#endif /* CONFIG_HAVE_JUMP_LABEL_HACK */
 
 static __always_inline bool arch_static_branch(struct static_key * const key, 
const bool branch)
 {
-       asm goto("1:"
-               ".byte " __stringify(BYTES_NOP5) "\n\t"
-               JUMP_TABLE_ENTRY
+       asm goto(ARCH_STATIC_BRANCH_ASM("%c0 + %c1", "%l[l_yes]")
                : :  "i" (key), "i" (branch) : : l_yes);
 
        return false;
@@ -48,13 +41,11 @@ static __always_inline bool arch_static_branch(struct 
static_key * const key, co
        return true;
 }
 
-#endif /* CONFIG_HAVE_JUMP_LABEL_HACK */
-
 static __always_inline bool arch_static_branch_jump(struct static_key * const 
key, const bool branch)
 {
        asm goto("1:"
                "jmp %l[l_yes]\n\t"
-               JUMP_TABLE_ENTRY
+               JUMP_TABLE_ENTRY("%c0 + %c1", "%l[l_yes]")
                : :  "i" (key), "i" (branch) : : l_yes);
 
        return false;

-- 
2.47.0.163.g1226f6d8fa-goog


Reply via email to