aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSrinivasa Ds <srinivasa@in.ibm.com>2008-09-23 05:53:52 -0400
committerIngo Molnar <mingo@elte.hu>2008-09-23 07:26:52 -0400
commitda654b74bda14c45a7d98c731bf3c1a43b6b74e2 (patch)
treee3cc6f1a1f7300c07e59c9091cd2ede0c5da8d4d
parent101d5b713700b902b1c200cdd1925c3cb7d34567 (diff)
signals: demultiplexing SIGTRAP signal
Currently a SIGTRAP can denote any one of below reasons. - Breakpoint hit - H/W debug register hit - Single step - Signal sent through kill() or rasie() Architectures like powerpc/parisc provides infrastructure to demultiplex SIGTRAP signal by passing down the information for receiving SIGTRAP through si_code of siginfot_t structure. Here is an attempt is generalise this infrastructure by extending it to x86 and x86_64 archs. Signed-off-by: Srinivasa DS <srinivasa@in.ibm.com> Cc: Roland McGrath <roland@redhat.com> Cc: akpm@linux-foundation.org Cc: paulus@samba.org Cc: linuxppc-dev@ozlabs.org Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--arch/ia64/include/asm/siginfo.h5
-rw-r--r--arch/powerpc/include/asm/siginfo.h5
-rw-r--r--arch/x86/kernel/ptrace.c7
-rw-r--r--arch/x86/kernel/traps_32.c4
-rw-r--r--arch/x86/kernel/traps_64.c2
-rw-r--r--include/asm-generic/siginfo.h2
-rw-r--r--include/asm-parisc/siginfo.h5
-rw-r--r--include/asm-x86/ptrace.h2
-rw-r--r--include/asm-x86/traps.h10
9 files changed, 21 insertions, 21 deletions
diff --git a/arch/ia64/include/asm/siginfo.h b/arch/ia64/include/asm/siginfo.h
index 9294e4b0c8bc..118d42979003 100644
--- a/arch/ia64/include/asm/siginfo.h
+++ b/arch/ia64/include/asm/siginfo.h
@@ -113,11 +113,6 @@ typedef struct siginfo {
113#undef NSIGSEGV 113#undef NSIGSEGV
114#define NSIGSEGV 3 114#define NSIGSEGV 3
115 115
116/*
117 * SIGTRAP si_codes
118 */
119#define TRAP_BRANCH (__SI_FAULT|3) /* process taken branch trap */
120#define TRAP_HWBKPT (__SI_FAULT|4) /* hardware breakpoint or watchpoint */
121#undef NSIGTRAP 116#undef NSIGTRAP
122#define NSIGTRAP 4 117#define NSIGTRAP 4
123 118
diff --git a/arch/powerpc/include/asm/siginfo.h b/arch/powerpc/include/asm/siginfo.h
index 12f1bce037be..49495b0534ed 100644
--- a/arch/powerpc/include/asm/siginfo.h
+++ b/arch/powerpc/include/asm/siginfo.h
@@ -15,11 +15,6 @@
15 15
16#include <asm-generic/siginfo.h> 16#include <asm-generic/siginfo.h>
17 17
18/*
19 * SIGTRAP si_codes
20 */
21#define TRAP_BRANCH (__SI_FAULT|3) /* process taken branch trap */
22#define TRAP_HWBKPT (__SI_FAULT|4) /* hardware breakpoint or watchpoint */
23#undef NSIGTRAP 18#undef NSIGTRAP
24#define NSIGTRAP 4 19#define NSIGTRAP 4
25 20
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 9e43a48ad6e0..bf45cdf1aaca 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -1358,7 +1358,8 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task)
1358#endif 1358#endif
1359} 1359}
1360 1360
1361void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code) 1361void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
1362 int error_code, int si_code)
1362{ 1363{
1363 struct siginfo info; 1364 struct siginfo info;
1364 1365
@@ -1367,7 +1368,7 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
1367 1368
1368 memset(&info, 0, sizeof(info)); 1369 memset(&info, 0, sizeof(info));
1369 info.si_signo = SIGTRAP; 1370 info.si_signo = SIGTRAP;
1370 info.si_code = TRAP_BRKPT; 1371 info.si_code = si_code;
1371 1372
1372 /* User-mode ip? */ 1373 /* User-mode ip? */
1373 info.si_addr = user_mode_vm(regs) ? (void __user *) regs->ip : NULL; 1374 info.si_addr = user_mode_vm(regs) ? (void __user *) regs->ip : NULL;
@@ -1454,5 +1455,5 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs)
1454 */ 1455 */
1455 if (test_thread_flag(TIF_SINGLESTEP) && 1456 if (test_thread_flag(TIF_SINGLESTEP) &&
1456 tracehook_consider_fatal_signal(current, SIGTRAP, SIG_DFL)) 1457 tracehook_consider_fatal_signal(current, SIGTRAP, SIG_DFL))
1457 send_sigtrap(current, regs, 0); 1458 send_sigtrap(current, regs, 0, TRAP_BRKPT);
1458} 1459}
diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c
index da5a5964fccb..0429c5de5ea9 100644
--- a/arch/x86/kernel/traps_32.c
+++ b/arch/x86/kernel/traps_32.c
@@ -891,6 +891,7 @@ void __kprobes do_debug(struct pt_regs *regs, long error_code)
891{ 891{
892 struct task_struct *tsk = current; 892 struct task_struct *tsk = current;
893 unsigned int condition; 893 unsigned int condition;
894 int si_code;
894 895
895 trace_hardirqs_fixup(); 896 trace_hardirqs_fixup();
896 897
@@ -935,8 +936,9 @@ void __kprobes do_debug(struct pt_regs *regs, long error_code)
935 goto clear_TF_reenable; 936 goto clear_TF_reenable;
936 } 937 }
937 938
939 si_code = get_si_code((unsigned long)condition);
938 /* Ok, finally something we can handle */ 940 /* Ok, finally something we can handle */
939 send_sigtrap(tsk, regs, error_code); 941 send_sigtrap(tsk, regs, error_code, si_code);
940 942
941 /* 943 /*
942 * Disable additional traps. They'll be re-enabled when 944 * Disable additional traps. They'll be re-enabled when
diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c
index 56d6f1147785..011d8e1fac6e 100644
--- a/arch/x86/kernel/traps_64.c
+++ b/arch/x86/kernel/traps_64.c
@@ -941,7 +941,7 @@ asmlinkage void __kprobes do_debug(struct pt_regs *regs,
941 tsk->thread.error_code = error_code; 941 tsk->thread.error_code = error_code;
942 info.si_signo = SIGTRAP; 942 info.si_signo = SIGTRAP;
943 info.si_errno = 0; 943 info.si_errno = 0;
944 info.si_code = TRAP_BRKPT; 944 info.si_code = get_si_code(condition);
945 info.si_addr = user_mode(regs) ? (void __user *)regs->ip : NULL; 945 info.si_addr = user_mode(regs) ? (void __user *)regs->ip : NULL;
946 force_sig_info(SIGTRAP, &info, tsk); 946 force_sig_info(SIGTRAP, &info, tsk);
947 947
diff --git a/include/asm-generic/siginfo.h b/include/asm-generic/siginfo.h
index 8786e01e0db8..969570167e9e 100644
--- a/include/asm-generic/siginfo.h
+++ b/include/asm-generic/siginfo.h
@@ -199,6 +199,8 @@ typedef struct siginfo {
199 */ 199 */
200#define TRAP_BRKPT (__SI_FAULT|1) /* process breakpoint */ 200#define TRAP_BRKPT (__SI_FAULT|1) /* process breakpoint */
201#define TRAP_TRACE (__SI_FAULT|2) /* process trace trap */ 201#define TRAP_TRACE (__SI_FAULT|2) /* process trace trap */
202#define TRAP_BRANCH (__SI_FAULT|3) /* process taken branch trap */
203#define TRAP_HWBKPT (__SI_FAULT|4) /* hardware breakpoint/watchpoint */
202#define NSIGTRAP 2 204#define NSIGTRAP 2
203 205
204/* 206/*
diff --git a/include/asm-parisc/siginfo.h b/include/asm-parisc/siginfo.h
index d4909f55fe35..d7034728f377 100644
--- a/include/asm-parisc/siginfo.h
+++ b/include/asm-parisc/siginfo.h
@@ -3,11 +3,6 @@
3 3
4#include <asm-generic/siginfo.h> 4#include <asm-generic/siginfo.h>
5 5
6/*
7 * SIGTRAP si_codes
8 */
9#define TRAP_BRANCH (__SI_FAULT|3) /* process taken branch trap */
10#define TRAP_HWBKPT (__SI_FAULT|4) /* hardware breakpoint or watchpoint */
11#undef NSIGTRAP 6#undef NSIGTRAP
12#define NSIGTRAP 4 7#define NSIGTRAP 4
13 8
diff --git a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h
index fad807769910..c2f368273079 100644
--- a/include/asm-x86/ptrace.h
+++ b/include/asm-x86/ptrace.h
@@ -143,7 +143,7 @@ convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs);
143 143
144#ifdef CONFIG_X86_32 144#ifdef CONFIG_X86_32
145extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, 145extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
146 int error_code); 146 int error_code, int si_code);
147#endif 147#endif
148 148
149void signal_fault(struct pt_regs *regs, void __user *frame, char *where); 149void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
diff --git a/include/asm-x86/traps.h b/include/asm-x86/traps.h
index 2ccebc6fb0b0..4b1e90409251 100644
--- a/include/asm-x86/traps.h
+++ b/include/asm-x86/traps.h
@@ -36,6 +36,16 @@ void do_invalid_op(struct pt_regs *, long);
36void do_general_protection(struct pt_regs *, long); 36void do_general_protection(struct pt_regs *, long);
37void do_nmi(struct pt_regs *, long); 37void do_nmi(struct pt_regs *, long);
38 38
39static inline int get_si_code(unsigned long condition)
40{
41 if (condition & DR_STEP)
42 return TRAP_TRACE;
43 else if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3))
44 return TRAP_HWBKPT;
45 else
46 return TRAP_BRKPT;
47}
48
39extern int panic_on_unrecovered_nmi; 49extern int panic_on_unrecovered_nmi;
40extern int kstack_depth_to_print; 50extern int kstack_depth_to_print;
41 51