aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2014-05-07 11:59:39 -0400
committerOleg Nesterov <oleg@redhat.com>2014-05-14 07:57:27 -0400
commit958d3d729802f7d741cbe8400e69b89baae580ee (patch)
tree3ed3667300363041c3e81a583db877807ee57589 /arch
parentdff0796e53c29147c9bd1f5567a261dcf0e528bc (diff)
x86/traps: Introduce fill_trap_info(), simplify DO_ERROR_INFO()
Extract the fill-siginfo code from DO_ERROR_INFO() into the new helper, fill_trap_info(). It can calculate si_code and si_addr looking at trapnr, so we can remove these arguments from DO_ERROR_INFO() and simplify the source code. The generated code is the same, __builtin_constant_p(trapnr) == T. Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/traps.c53
1 files changed, 38 insertions, 15 deletions
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index ab8dad719b9e..1cf8a4c409b6 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -136,6 +136,33 @@ do_trap_no_signal(struct task_struct *tsk, int trapnr, char *str,
136 return -1; 136 return -1;
137} 137}
138 138
139static void fill_trap_info(struct pt_regs *regs, int signr, int trapnr,
140 siginfo_t *info)
141{
142 unsigned long siaddr;
143 int sicode;
144
145 switch (trapnr) {
146 case X86_TRAP_DE:
147 sicode = FPE_INTDIV;
148 siaddr = regs->ip;
149 break;
150 case X86_TRAP_UD:
151 sicode = ILL_ILLOPN;
152 siaddr = regs->ip;
153 break;
154 case X86_TRAP_AC:
155 sicode = BUS_ADRALN;
156 siaddr = 0;
157 break;
158 }
159
160 info->si_signo = signr;
161 info->si_errno = 0;
162 info->si_code = sicode;
163 info->si_addr = (void __user *)siaddr;
164}
165
139static void __kprobes 166static void __kprobes
140do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, 167do_trap(int trapnr, int signr, char *str, struct pt_regs *regs,
141 long error_code, siginfo_t *info) 168 long error_code, siginfo_t *info)
@@ -191,30 +218,26 @@ dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \
191 do_error_trap(regs, error_code, str, trapnr, signr, NULL); \ 218 do_error_trap(regs, error_code, str, trapnr, signr, NULL); \
192} 219}
193 220
194#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \ 221#define DO_ERROR_INFO(trapnr, signr, str, name) \
195dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \ 222dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \
196{ \ 223{ \
197 siginfo_t info; \ 224 siginfo_t info; \
198 \ 225 \
199 info.si_signo = signr; \ 226 fill_trap_info(regs, signr, trapnr, &info); \
200 info.si_errno = 0; \
201 info.si_code = sicode; \
202 info.si_addr = (void __user *)siaddr; \
203 \
204 do_error_trap(regs, error_code, str, trapnr, signr, &info); \ 227 do_error_trap(regs, error_code, str, trapnr, signr, &info); \
205} 228}
206 229
207DO_ERROR_INFO(X86_TRAP_DE, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->ip ) 230DO_ERROR_INFO(X86_TRAP_DE, SIGFPE, "divide error", divide_error)
208DO_ERROR (X86_TRAP_OF, SIGSEGV, "overflow", overflow ) 231DO_ERROR (X86_TRAP_OF, SIGSEGV, "overflow", overflow)
209DO_ERROR (X86_TRAP_BR, SIGSEGV, "bounds", bounds ) 232DO_ERROR (X86_TRAP_BR, SIGSEGV, "bounds", bounds)
210DO_ERROR_INFO(X86_TRAP_UD, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip ) 233DO_ERROR_INFO(X86_TRAP_UD, SIGILL, "invalid opcode", invalid_op)
211DO_ERROR (X86_TRAP_OLD_MF, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun ) 234DO_ERROR (X86_TRAP_OLD_MF, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun)
212DO_ERROR (X86_TRAP_TS, SIGSEGV, "invalid TSS", invalid_TSS ) 235DO_ERROR (X86_TRAP_TS, SIGSEGV, "invalid TSS", invalid_TSS)
213DO_ERROR (X86_TRAP_NP, SIGBUS, "segment not present", segment_not_present ) 236DO_ERROR (X86_TRAP_NP, SIGBUS, "segment not present", segment_not_present)
214#ifdef CONFIG_X86_32 237#ifdef CONFIG_X86_32
215DO_ERROR (X86_TRAP_SS, SIGBUS, "stack segment", stack_segment ) 238DO_ERROR (X86_TRAP_SS, SIGBUS, "stack segment", stack_segment)
216#endif 239#endif
217DO_ERROR_INFO(X86_TRAP_AC, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0 ) 240DO_ERROR_INFO(X86_TRAP_AC, SIGBUS, "alignment check", alignment_check)
218 241
219#ifdef CONFIG_X86_64 242#ifdef CONFIG_X86_64
220/* Runs on IST stack */ 243/* Runs on IST stack */