summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm64/include/asm/ktext.h1
-rw-r--r--arch/arm64/kernel/patching.c2
-rw-r--r--arch/arm64/mm/ktext.c21
3 files changed, 24 insertions, 0 deletions
diff --git a/arch/arm64/include/asm/ktext.h b/arch/arm64/include/asm/ktext.h
index 289e11289c06..def0c894ed46 100644
--- a/arch/arm64/include/asm/ktext.h
+++ b/arch/arm64/include/asm/ktext.h
@@ -10,6 +10,7 @@
#ifdef CONFIG_REPLICATE_KTEXT
void ktext_replication_init(void);
+void ktext_replication_write(void *addr, void *data, size_t size);
void __kprobes ktext_replication_patch(u32 *tp, __le32 insn);
void ktext_replication_patch_alternative(__le32 *src, int nr_inst);
diff --git a/arch/arm64/kernel/patching.c b/arch/arm64/kernel/patching.c
index 627fff6ddda2..b670e159a766 100644
--- a/arch/arm64/kernel/patching.c
+++ b/arch/arm64/kernel/patching.c
@@ -103,6 +103,8 @@ noinstr int aarch64_insn_write_literal_u64(void *addr, u64 val)
patch_unmap(FIX_TEXT_POKE0);
raw_spin_unlock_irqrestore(&patch_lock, flags);
+ ktext_replication_write(addr, &val, sizeof(val));
+
return ret;
}
diff --git a/arch/arm64/mm/ktext.c b/arch/arm64/mm/ktext.c
index 04b5ceddae4e..0017e7760d36 100644
--- a/arch/arm64/mm/ktext.c
+++ b/arch/arm64/mm/ktext.c
@@ -17,6 +17,27 @@
static void *kernel_texts[MAX_NUMNODES];
+noinstr void ktext_replication_write(void *addr, void *data, size_t size)
+{
+ unsigned long offset;
+ void *ptr;
+ int nid;
+
+ if (!is_kernel_text((unsigned long)addr))
+ return;
+
+ offset = (unsigned long)addr - (unsigned long)_stext;
+
+ for_each_node(nid) {
+ if (!kernel_texts[nid] || !nid)
+ continue;
+
+ ptr = kernel_texts[nid] + offset;
+
+ memcpy(ptr, data, size);
+ }
+}
+
void __kprobes ktext_replication_patch(u32 *tp, __le32 insn)
{
unsigned long offset;