]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
tile: define a macro ktext_writable_addr to get writable kernel text address
authorZhigang Lu <zlu@ezchip.com>
Wed, 30 Sep 2015 01:53:47 +0000 (09:53 +0800)
committerChris Metcalf <cmetcalf@ezchip.com>
Tue, 20 Oct 2015 20:39:42 +0000 (16:39 -0400)
It is used by kgdb, ftrace, kprobe and jump label, so we factor
this out into a helper routine.

Reviewed-by: Chris Metcalf <cmetcalf@ezchip.com>
Signed-off-by: Zhigang Lu <zlu@ezchip.com>
Signed-off-by: Chris Metcalf <cmetcalf@ezchip.com>
arch/tile/include/asm/page.h
arch/tile/kernel/ftrace.c
arch/tile/kernel/kgdb.c
arch/tile/kernel/kprobes.c

index a213a8d84a95ac48a149de807558290c21dbe2cb..5cee2cbff2b1b0fd5e094a0cd5a87ee520cc6895 100644 (file)
@@ -319,6 +319,16 @@ static inline int pfn_valid(unsigned long pfn)
 #define virt_to_page(kaddr) pfn_to_page(kaddr_to_pfn((void *)(kaddr)))
 #define page_to_virt(page) pfn_to_kaddr(page_to_pfn(page))
 
+/*
+ * The kernel text is mapped at MEM_SV_START as read-only.  To allow
+ * modifying kernel text, it is also mapped at PAGE_OFFSET as read-write.
+ * This macro converts a kernel address to its writable kernel text mapping,
+ * which is used to modify the text code on a running kernel by kgdb,
+ * ftrace, kprobe, jump label, etc.
+ */
+#define ktext_writable_addr(kaddr) \
+       ((unsigned long)(kaddr) - MEM_SV_START + PAGE_OFFSET)
+
 struct mm_struct;
 extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr);
 extern pte_t *virt_to_kpte(unsigned long kaddr);
index 0c0996175b1ed613cf6fe4d3e89cec85ea5c6a6f..4180ccdf9cd090db1985ca726e7af33e53843875 100644 (file)
@@ -117,7 +117,7 @@ static int ftrace_modify_code(unsigned long pc, unsigned long old,
                return -EINVAL;
 
        /* Operate on writable kernel text mapping. */
-       pc_wr = pc - MEM_SV_START + PAGE_OFFSET;
+       pc_wr = ktext_writable_addr(pc);
 
        if (probe_kernel_write((void *)pc_wr, &new, MCOUNT_INSN_SIZE))
                return -EPERM;
index ff5335ae050d475dcff52fb0a53c484abaee6a56..a506c2c28943715770ab43fa451797a8cb1566e4 100644 (file)
@@ -164,7 +164,7 @@ static unsigned long writable_address(unsigned long addr)
        unsigned long ret = 0;
 
        if (core_kernel_text(addr))
-               ret = addr - MEM_SV_START + PAGE_OFFSET;
+               ret = ktext_writable_addr(addr);
        else if (is_module_text_address(addr))
                ret = addr;
        else
index f8a45c51e9e48c057897d1c28de11ad3e7b0a3c7..c68694bb1ad2b3fb81121fd8733b233049a19290 100644 (file)
@@ -116,7 +116,7 @@ void __kprobes arch_arm_kprobe(struct kprobe *p)
        unsigned long addr_wr;
 
        /* Operate on writable kernel text mapping. */
-       addr_wr = (unsigned long)p->addr - MEM_SV_START + PAGE_OFFSET;
+       addr_wr = ktext_writable_addr(p->addr);
 
        if (probe_kernel_write((void *)addr_wr, &breakpoint_insn,
                sizeof(breakpoint_insn)))
@@ -131,7 +131,7 @@ void __kprobes arch_disarm_kprobe(struct kprobe *kp)
        unsigned long addr_wr;
 
        /* Operate on writable kernel text mapping. */
-       addr_wr = (unsigned long)kp->addr - MEM_SV_START + PAGE_OFFSET;
+       addr_wr = ktext_writable_addr(kp->addr);
 
        if (probe_kernel_write((void *)addr_wr, &kp->opcode,
                sizeof(kp->opcode)))