diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2013-08-01 10:16:27 +0200 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2013-08-22 12:20:12 +0200 |
commit | 6b169ac9b4342ff3a1499bdeb7596aa4f1bc401b (patch) | |
tree | 3697bebddba3158aefd5481e7009ecd5ae5a1291 /arch/s390/kernel/kprobes.c | |
parent | bee5c2863ef807fa50bbdf8b2bae887c54a97083 (diff) | |
download | linux-6b169ac9b4342ff3a1499bdeb7596aa4f1bc401b.tar.gz linux-6b169ac9b4342ff3a1499bdeb7596aa4f1bc401b.tar.bz2 linux-6b169ac9b4342ff3a1499bdeb7596aa4f1bc401b.zip |
s390/kprobes: add support for compare and branch instructions
The compare and branch instructions (not relative) all need special
handling when kprobed:
- if a branch was taken, the instruction pointer should be left alone
- if a branch was not taken, the instruction pointer must be adjusted
The compare and branch instructions family was introduced with the general
instruction extension facility (z10).
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/kprobes.c')
-rw-r--r-- | arch/s390/kernel/kprobes.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c index 3388b2b2a07d..adbbe7f1cb0d 100644 --- a/arch/s390/kernel/kprobes.c +++ b/arch/s390/kernel/kprobes.c @@ -105,14 +105,31 @@ static int __kprobes get_fixup_type(kprobe_opcode_t *insn) fixup |= FIXUP_RETURN_REGISTER; break; case 0xeb: - if ((insn[2] & 0xff) == 0x44 || /* bxhg */ - (insn[2] & 0xff) == 0x45) /* bxleg */ + switch (insn[2] & 0xff) { + case 0x44: /* bxhg */ + case 0x45: /* bxleg */ fixup = FIXUP_BRANCH_NOT_TAKEN; + break; + } break; case 0xe3: /* bctg */ if ((insn[2] & 0xff) == 0x46) fixup = FIXUP_BRANCH_NOT_TAKEN; break; + case 0xec: + switch (insn[2] & 0xff) { + case 0xe5: /* clgrb */ + case 0xe6: /* cgrb */ + case 0xf6: /* crb */ + case 0xf7: /* clrb */ + case 0xfc: /* cgib */ + case 0xfd: /* cglib */ + case 0xfe: /* cib */ + case 0xff: /* clib */ + fixup = FIXUP_BRANCH_NOT_TAKEN; + break; + } + break; } return fixup; } |