diff options
author | Jan Willeke <willeke@de.ibm.com> | 2014-09-22 10:39:06 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2014-09-25 04:52:17 -0400 |
commit | 2a0a5b2299b9bef76123fac91e68d39cb361c33e (patch) | |
tree | fa8872070bf295dbbc57e7063db6e6baf739f543 /arch/s390/kernel/traps.c | |
parent | 975fab17399a2b29985166181ad80e5f50fa42e9 (diff) |
s390/uprobes: architecture backend for uprobes
Signed-off-by: Jan Willeke <willeke@de.ibm.com>
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/traps.c')
-rw-r--r-- | arch/s390/kernel/traps.c | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index c5762324d9ee..e3e06a4fdfce 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c | |||
@@ -58,15 +58,10 @@ int is_valid_bugaddr(unsigned long addr) | |||
58 | return 1; | 58 | return 1; |
59 | } | 59 | } |
60 | 60 | ||
61 | static void __kprobes do_trap(struct pt_regs *regs, | 61 | void do_report_trap(struct pt_regs *regs, int si_signo, int si_code, char *str) |
62 | int si_signo, int si_code, char *str) | ||
63 | { | 62 | { |
64 | siginfo_t info; | 63 | siginfo_t info; |
65 | 64 | ||
66 | if (notify_die(DIE_TRAP, str, regs, 0, | ||
67 | regs->int_code, si_signo) == NOTIFY_STOP) | ||
68 | return; | ||
69 | |||
70 | if (user_mode(regs)) { | 65 | if (user_mode(regs)) { |
71 | info.si_signo = si_signo; | 66 | info.si_signo = si_signo; |
72 | info.si_errno = 0; | 67 | info.si_errno = 0; |
@@ -90,6 +85,15 @@ static void __kprobes do_trap(struct pt_regs *regs, | |||
90 | } | 85 | } |
91 | } | 86 | } |
92 | 87 | ||
88 | static void __kprobes do_trap(struct pt_regs *regs, int si_signo, int si_code, | ||
89 | char *str) | ||
90 | { | ||
91 | if (notify_die(DIE_TRAP, str, regs, 0, | ||
92 | regs->int_code, si_signo) == NOTIFY_STOP) | ||
93 | return; | ||
94 | do_report_trap(regs, si_signo, si_code, str); | ||
95 | } | ||
96 | |||
93 | void __kprobes do_per_trap(struct pt_regs *regs) | 97 | void __kprobes do_per_trap(struct pt_regs *regs) |
94 | { | 98 | { |
95 | siginfo_t info; | 99 | siginfo_t info; |
@@ -178,6 +182,7 @@ void __kprobes illegal_op(struct pt_regs *regs) | |||
178 | siginfo_t info; | 182 | siginfo_t info; |
179 | __u8 opcode[6]; | 183 | __u8 opcode[6]; |
180 | __u16 __user *location; | 184 | __u16 __user *location; |
185 | int is_uprobe_insn = 0; | ||
181 | int signal = 0; | 186 | int signal = 0; |
182 | 187 | ||
183 | location = get_trap_ip(regs); | 188 | location = get_trap_ip(regs); |
@@ -194,6 +199,10 @@ void __kprobes illegal_op(struct pt_regs *regs) | |||
194 | force_sig_info(SIGTRAP, &info, current); | 199 | force_sig_info(SIGTRAP, &info, current); |
195 | } else | 200 | } else |
196 | signal = SIGILL; | 201 | signal = SIGILL; |
202 | #ifdef CONFIG_UPROBES | ||
203 | } else if (*((__u16 *) opcode) == UPROBE_SWBP_INSN) { | ||
204 | is_uprobe_insn = 1; | ||
205 | #endif | ||
197 | #ifdef CONFIG_MATHEMU | 206 | #ifdef CONFIG_MATHEMU |
198 | } else if (opcode[0] == 0xb3) { | 207 | } else if (opcode[0] == 0xb3) { |
199 | if (get_user(*((__u16 *) (opcode+2)), location+1)) | 208 | if (get_user(*((__u16 *) (opcode+2)), location+1)) |
@@ -219,11 +228,13 @@ void __kprobes illegal_op(struct pt_regs *regs) | |||
219 | #endif | 228 | #endif |
220 | } else | 229 | } else |
221 | signal = SIGILL; | 230 | signal = SIGILL; |
222 | } else { | 231 | } |
223 | /* | 232 | /* |
224 | * If we get an illegal op in kernel mode, send it through the | 233 | * We got either an illegal op in kernel mode, or user space trapped |
225 | * kprobes notifier. If kprobes doesn't pick it up, SIGILL | 234 | * on a uprobes illegal instruction. See if kprobes or uprobes picks |
226 | */ | 235 | * it up. If not, SIGILL. |
236 | */ | ||
237 | if (is_uprobe_insn || !user_mode(regs)) { | ||
227 | if (notify_die(DIE_BPT, "bpt", regs, 0, | 238 | if (notify_die(DIE_BPT, "bpt", regs, 0, |
228 | 3, SIGTRAP) != NOTIFY_STOP) | 239 | 3, SIGTRAP) != NOTIFY_STOP) |
229 | signal = SIGILL; | 240 | signal = SIGILL; |