|
@@ -23,7 +23,9 @@
|
|
|
#include <linux/slab.h>
|
|
|
#include <linux/stop_machine.h>
|
|
|
#include <linux/sched/debug.h>
|
|
|
+#include <linux/set_memory.h>
|
|
|
#include <linux/stringify.h>
|
|
|
+#include <linux/vmalloc.h>
|
|
|
#include <asm/traps.h>
|
|
|
#include <asm/ptrace.h>
|
|
|
#include <asm/cacheflush.h>
|
|
@@ -42,10 +44,21 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
|
|
|
static void __kprobes
|
|
|
post_kprobe_handler(struct kprobe_ctlblk *, struct pt_regs *);
|
|
|
|
|
|
+static int __kprobes patch_text(kprobe_opcode_t *addr, u32 opcode)
|
|
|
+{
|
|
|
+ void *addrs[1];
|
|
|
+ u32 insns[1];
|
|
|
+
|
|
|
+ addrs[0] = addr;
|
|
|
+ insns[0] = opcode;
|
|
|
+
|
|
|
+ return aarch64_insn_patch_text(addrs, insns, 1);
|
|
|
+}
|
|
|
+
|
|
|
static void __kprobes arch_prepare_ss_slot(struct kprobe *p)
|
|
|
{
|
|
|
/* prepare insn slot */
|
|
|
- p->ainsn.api.insn[0] = cpu_to_le32(p->opcode);
|
|
|
+ patch_text(p->ainsn.api.insn, p->opcode);
|
|
|
|
|
|
flush_icache_range((uintptr_t) (p->ainsn.api.insn),
|
|
|
(uintptr_t) (p->ainsn.api.insn) +
|
|
@@ -118,15 +131,15 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int __kprobes patch_text(kprobe_opcode_t *addr, u32 opcode)
|
|
|
+void *alloc_insn_page(void)
|
|
|
{
|
|
|
- void *addrs[1];
|
|
|
- u32 insns[1];
|
|
|
+ void *page;
|
|
|
|
|
|
- addrs[0] = (void *)addr;
|
|
|
- insns[0] = (u32)opcode;
|
|
|
+ page = vmalloc_exec(PAGE_SIZE);
|
|
|
+ if (page)
|
|
|
+ set_memory_ro((unsigned long)page, 1);
|
|
|
|
|
|
- return aarch64_insn_patch_text(addrs, insns, 1);
|
|
|
+ return page;
|
|
|
}
|
|
|
|
|
|
/* arm kprobe: install breakpoint in text */
|