diff options
author | Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> | 2005-06-23 00:09:34 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-23 09:45:24 -0700 |
commit | 708de8f11c2901cc49fd7725baf4a0fbd7264e73 (patch) | |
tree | a78c45c153c6414908104547292c177bcf309908 /arch/ia64/kernel/kprobes.c | |
parent | 1674eafcbd3e3c68556cf19fbf4a2c30f7add729 (diff) | |
download | op-kernel-dev-708de8f11c2901cc49fd7725baf4a0fbd7264e73.zip op-kernel-dev-708de8f11c2901cc49fd7725baf4a0fbd7264e73.tar.gz |
[PATCH] Kprobes IA64: safe register kprobe
The current kprobes does not yet handle register kprobes on some of the
following kind of instruction which needs to be emulated in a special way.
1) mov r1=ip
2) chk -- Speculation check instruction
This patch attempts to fail register_kprobes() when user tries to insert
kprobes on the above kind of instruction.
Signed-off-by: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/ia64/kernel/kprobes.c')
-rw-r--r-- | arch/ia64/kernel/kprobes.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c index 51bc08b..027d656 100644 --- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c @@ -121,6 +121,48 @@ static void update_kprobe_inst_flag(uint template, uint slot, uint major_opcode /* * In this function we check to see if the instruction + * on which we are inserting kprobe is supported. + * Returns 0 if supported + * Returns -EINVAL if unsupported + */ +static int unsupported_inst(uint template, uint slot, uint major_opcode, + unsigned long kprobe_inst, struct kprobe *p) +{ + unsigned long addr = (unsigned long)p->addr; + + if (bundle_encoding[template][slot] == I) { + switch (major_opcode) { + case 0x0: //I_UNIT_MISC_OPCODE: + /* + * Check for Integer speculation instruction + * - Bit 33-35 to be equal to 0x1 + */ + if (((kprobe_inst >> 33) & 0x7) == 1) { + printk(KERN_WARNING + "Kprobes on speculation inst at <0x%lx> not supported\n", + addr); + return -EINVAL; + } + + /* + * IP relative mov instruction + * - Bit 27-35 to be equal to 0x30 + */ + if (((kprobe_inst >> 27) & 0x1FF) == 0x30) { + printk(KERN_WARNING + "Kprobes on \"mov r1=ip\" at <0x%lx> not supported\n", + addr); + return -EINVAL; + + } + } + } + return 0; +} + + +/* + * In this function we check to see if the instruction * (qp) cmpx.crel.ctype p1,p2=r2,r3 * on which we are inserting kprobe is cmp instruction * with ctype as unc. @@ -254,6 +296,9 @@ int arch_prepare_kprobe(struct kprobe *p) /* Get kprobe_inst and major_opcode from the bundle */ get_kprobe_inst(bundle, slot, &kprobe_inst, &major_opcode); + if (unsupported_inst(template, slot, major_opcode, kprobe_inst, p)) + return -EINVAL; + prepare_break_inst(template, slot, major_opcode, kprobe_inst, p); return 0; |