Commit f419e6f6 authored by Zhigang Lu's avatar Zhigang Lu Committed by Chris Metcalf

tile: define a macro ktext_writable_addr to get writable kernel text address

It is used by kgdb, ftrace, kprobe and jump label, so we factor
this out into a helper routine.
Reviewed-by: default avatarChris Metcalf <cmetcalf@ezchip.com>
Signed-off-by: default avatarZhigang Lu <zlu@ezchip.com>
Signed-off-by: default avatarChris Metcalf <cmetcalf@ezchip.com>
parent 9f9499ae
...@@ -319,6 +319,16 @@ static inline int pfn_valid(unsigned long pfn) ...@@ -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 virt_to_page(kaddr) pfn_to_page(kaddr_to_pfn((void *)(kaddr)))
#define page_to_virt(page) pfn_to_kaddr(page_to_pfn(page)) #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; struct mm_struct;
extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr); extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr);
extern pte_t *virt_to_kpte(unsigned long kaddr); extern pte_t *virt_to_kpte(unsigned long kaddr);
......
...@@ -117,7 +117,7 @@ static int ftrace_modify_code(unsigned long pc, unsigned long old, ...@@ -117,7 +117,7 @@ static int ftrace_modify_code(unsigned long pc, unsigned long old,
return -EINVAL; return -EINVAL;
/* Operate on writable kernel text mapping. */ /* 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)) if (probe_kernel_write((void *)pc_wr, &new, MCOUNT_INSN_SIZE))
return -EPERM; return -EPERM;
......
...@@ -164,7 +164,7 @@ static unsigned long writable_address(unsigned long addr) ...@@ -164,7 +164,7 @@ static unsigned long writable_address(unsigned long addr)
unsigned long ret = 0; unsigned long ret = 0;
if (core_kernel_text(addr)) if (core_kernel_text(addr))
ret = addr - MEM_SV_START + PAGE_OFFSET; ret = ktext_writable_addr(addr);
else if (is_module_text_address(addr)) else if (is_module_text_address(addr))
ret = addr; ret = addr;
else else
......
...@@ -116,7 +116,7 @@ void __kprobes arch_arm_kprobe(struct kprobe *p) ...@@ -116,7 +116,7 @@ void __kprobes arch_arm_kprobe(struct kprobe *p)
unsigned long addr_wr; unsigned long addr_wr;
/* Operate on writable kernel text mapping. */ /* 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, if (probe_kernel_write((void *)addr_wr, &breakpoint_insn,
sizeof(breakpoint_insn))) sizeof(breakpoint_insn)))
...@@ -131,7 +131,7 @@ void __kprobes arch_disarm_kprobe(struct kprobe *kp) ...@@ -131,7 +131,7 @@ void __kprobes arch_disarm_kprobe(struct kprobe *kp)
unsigned long addr_wr; unsigned long addr_wr;
/* Operate on writable kernel text mapping. */ /* 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, if (probe_kernel_write((void *)addr_wr, &kp->opcode,
sizeof(kp->opcode))) sizeof(kp->opcode)))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment