aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2009-06-12 04:26:43 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2009-06-12 04:27:37 -0400
commita2b53673fae14601bb520acf6a6f154463994565 (patch)
tree0733d6561a714820246cf780ab587913317a53a7
parent88df125fd6127e409793fd84a574566651450320 (diff)
[S390] kprobes: use probe_kernel_write
Use proble_kernel_write() to patch the kernel. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--arch/s390/kernel/kprobes.c31
1 files changed, 2 insertions, 29 deletions
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
index a01cf0284db2..9bb2f6241d9f 100644
--- a/arch/s390/kernel/kprobes.c
+++ b/arch/s390/kernel/kprobes.c
@@ -25,9 +25,9 @@
25#include <linux/preempt.h> 25#include <linux/preempt.h>
26#include <linux/stop_machine.h> 26#include <linux/stop_machine.h>
27#include <linux/kdebug.h> 27#include <linux/kdebug.h>
28#include <linux/uaccess.h>
28#include <asm/cacheflush.h> 29#include <asm/cacheflush.h>
29#include <asm/sections.h> 30#include <asm/sections.h>
30#include <asm/uaccess.h>
31#include <linux/module.h> 31#include <linux/module.h>
32 32
33DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; 33DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
@@ -155,35 +155,8 @@ void __kprobes get_instruction_type(struct arch_specific_insn *ainsn)
155static int __kprobes swap_instruction(void *aref) 155static int __kprobes swap_instruction(void *aref)
156{ 156{
157 struct ins_replace_args *args = aref; 157 struct ins_replace_args *args = aref;
158 u32 *addr;
159 u32 instr;
160 int err = -EFAULT;
161 158
162 /* 159 return probe_kernel_write(args->ptr, &args->new, sizeof(args->new));
163 * Text segment is read-only, hence we use stura to bypass dynamic
164 * address translation to exchange the instruction. Since stura
165 * always operates on four bytes, but we only want to exchange two
166 * bytes do some calculations to get things right. In addition we
167 * shall not cross any page boundaries (vmalloc area!) when writing
168 * the new instruction.
169 */
170 addr = (u32 *)((unsigned long)args->ptr & -4UL);
171 if ((unsigned long)args->ptr & 2)
172 instr = ((*addr) & 0xffff0000) | args->new;
173 else
174 instr = ((*addr) & 0x0000ffff) | args->new << 16;
175
176 asm volatile(
177 " lra %1,0(%1)\n"
178 "0: stura %2,%1\n"
179 "1: la %0,0\n"
180 "2:\n"
181 EX_TABLE(0b,2b)
182 : "+d" (err)
183 : "a" (addr), "d" (instr)
184 : "memory", "cc");
185
186 return err;
187} 160}
188 161
189void __kprobes arch_arm_kprobe(struct kprobe *p) 162void __kprobes arch_arm_kprobe(struct kprobe *p)