]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
LoongArch: Batch the icache maintenance for jump_label
authorYouling Tang <tangyouling@kylinos.cn>
Wed, 22 Apr 2026 07:45:13 +0000 (15:45 +0800)
committerHuacai Chen <chenhuacai@loongson.cn>
Wed, 22 Apr 2026 07:45:13 +0000 (15:45 +0800)
Switch to the batched version of the jump label update functions so
instruction cache maintenance is deferred until the end of the update.

Signed-off-by: Youling Tang <tangyouling@kylinos.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
arch/loongarch/include/asm/jump_label.h
arch/loongarch/kernel/inst.c
arch/loongarch/kernel/jump_label.c

index dcaecf69ea5a6064177a7b829cc1e4ec19a6f569..7ef4ae3abf0810dd9e325db8c3fe96c61f9e361d 100644 (file)
@@ -13,6 +13,8 @@
 #include <linux/stringify.h>
 #include <asm/asm.h>
 
+#define HAVE_JUMP_LABEL_BATCH
+
 #define JUMP_LABEL_NOP_SIZE    4
 
 #ifdef CONFIG_32BIT
index 1a728082944cb2eef89c46f24d0b06332ed3dc1c..0b9228b7c13a40465ac98098b6c8ab3b62895aaa 100644 (file)
@@ -209,6 +209,9 @@ int larch_insn_write(void *addr, u32 insn)
        int ret;
        unsigned long flags = 0;
 
+       if ((unsigned long)addr & 3)
+               return -EINVAL;
+
        raw_spin_lock_irqsave(&patch_lock, flags);
        ret = copy_to_kernel_nofault(addr, &insn, LOONGARCH_INSN_SIZE);
        raw_spin_unlock_irqrestore(&patch_lock, flags);
@@ -221,9 +224,6 @@ int larch_insn_patch_text(void *addr, u32 insn)
        int ret;
        u32 *tp = addr;
 
-       if ((unsigned long)tp & 3)
-               return -EINVAL;
-
        ret = larch_insn_write(tp, insn);
        if (!ret)
                flush_icache_range((unsigned long)tp,
index 31891214b767e71c96590bf6d58317bdc4874d54..24a3f4d8540c5d6fb318f406ac4d7ad2d3678bd2 100644 (file)
@@ -6,9 +6,10 @@
  */
 #include <linux/kernel.h>
 #include <linux/jump_label.h>
+#include <asm/cacheflush.h>
 #include <asm/inst.h>
 
-void arch_jump_label_transform(struct jump_entry *entry, enum jump_label_type type)
+bool arch_jump_label_transform_queue(struct jump_entry *entry, enum jump_label_type type)
 {
        u32 insn;
        void *addr = (void *)jump_entry_code(entry);
@@ -18,5 +19,12 @@ void arch_jump_label_transform(struct jump_entry *entry, enum jump_label_type ty
        else
                insn = larch_insn_gen_nop();
 
-       larch_insn_patch_text(addr, insn);
+       larch_insn_write(addr, insn);
+
+       return true;
+}
+
+void arch_jump_label_transform_apply(void)
+{
+       flush_icache_all();
 }