1
2
3
4
5
6
7
8
9
10
11
12
13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14
15#include <linux/context_tracking.h>
16#include <linux/interrupt.h>
17#include <linux/kallsyms.h>
18#include <linux/spinlock.h>
19#include <linux/kprobes.h>
20#include <linux/uaccess.h>
21#include <linux/kdebug.h>
22#include <linux/kgdb.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/ptrace.h>
26#include <linux/string.h>
27#include <linux/delay.h>
28#include <linux/errno.h>
29#include <linux/kexec.h>
30#include <linux/sched.h>
31#include <linux/timer.h>
32#include <linux/init.h>
33#include <linux/bug.h>
34#include <linux/nmi.h>
35#include <linux/mm.h>
36#include <linux/smp.h>
37#include <linux/io.h>
38
39#ifdef CONFIG_EISA
40#include <linux/ioport.h>
41#include <linux/eisa.h>
42#endif
43
44#if defined(CONFIG_EDAC)
45#include <linux/edac.h>
46#endif
47
48#include <asm/kmemcheck.h>
49#include <asm/stacktrace.h>
50#include <asm/processor.h>
51#include <asm/debugreg.h>
52#include <linux/atomic.h>
53#include <asm/ftrace.h>
54#include <asm/traps.h>
55#include <asm/desc.h>
56#include <asm/i387.h>
57#include <asm/fpu-internal.h>
58#include <asm/mce.h>
59#include <asm/fixmap.h>
60#include <asm/mach_traps.h>
61
62#ifdef CONFIG_X86_64
63#include <asm/x86_init.h>
64#include <asm/pgalloc.h>
65#include <asm/proto.h>
66#else
67#include <asm/processor-flags.h>
68#include <asm/setup.h>
69
70asmlinkage int system_call(void);
71
72
73
74
75
76gate_desc idt_table[NR_VECTORS] __page_aligned_data = { { { { 0, 0 } } }, };
77#endif
78
79DECLARE_BITMAP(used_vectors, NR_VECTORS);
80EXPORT_SYMBOL_GPL(used_vectors);
81
82static inline void conditional_sti(struct pt_regs *regs)
83{
84 if (regs->flags & X86_EFLAGS_IF)
85 local_irq_enable();
86}
87
88static inline void preempt_conditional_sti(struct pt_regs *regs)
89{
90 inc_preempt_count();
91 if (regs->flags & X86_EFLAGS_IF)
92 local_irq_enable();
93}
94
95static inline void conditional_cli(struct pt_regs *regs)
96{
97 if (regs->flags & X86_EFLAGS_IF)
98 local_irq_disable();
99}
100
101static inline void preempt_conditional_cli(struct pt_regs *regs)
102{
103 if (regs->flags & X86_EFLAGS_IF)
104 local_irq_disable();
105 dec_preempt_count();
106}
107
108static int __kprobes
109do_trap_no_signal(struct task_struct *tsk, int trapnr, char *str,
110 struct pt_regs *regs, long error_code)
111{
112#ifdef CONFIG_X86_32
113 if (regs->flags & X86_VM_MASK) {
114
115
116
117
118 if (trapnr < X86_TRAP_UD) {
119 if (!handle_vm86_trap((struct kernel_vm86_regs *) regs,
120 error_code, trapnr))
121 return 0;
122 }
123 return -1;
124 }
125#endif
126 if (!user_mode(regs)) {
127 if (!fixup_exception(regs)) {
128 tsk->thread.error_code = error_code;
129 tsk->thread.trap_nr = trapnr;
130 die(str, regs, error_code);
131 }
132 return 0;
133 }
134
135 return -1;
136}
137
138static void __kprobes
139do_trap(int trapnr, int signr, char *str, struct pt_regs *regs,
140 long error_code, siginfo_t *info)
141{
142 struct task_struct *tsk = current;
143
144
145 if (!do_trap_no_signal(tsk, trapnr, str, regs, error_code))
146 return;
147
148
149
150
151
152
153
154
155
156 tsk->thread.error_code = error_code;
157 tsk->thread.trap_nr = trapnr;
158
159#ifdef CONFIG_X86_64
160 if (show_unhandled_signals && unhandled_signal(tsk, signr) &&
161 printk_ratelimit()) {
162 pr_info("%s[%d] trap %s ip:%lx sp:%lx error:%lx",
163 tsk->comm, tsk->pid, str,
164 regs->ip, regs->sp, error_code);
165 print_vma_addr(" in ", regs->ip);
166 pr_cont("\n");
167 }
168#endif
169
170 if (info)
171 force_sig_info(signr, info, tsk);
172 else
173 force_sig(signr, tsk);
174}
175
176#define DO_ERROR(trapnr, signr, str, name) \
177dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \
178{ \
179 enum ctx_state prev_state; \
180 \
181 prev_state = exception_enter(); \
182 if (notify_die(DIE_TRAP, str, regs, error_code, \
183 trapnr, signr) == NOTIFY_STOP) { \
184 exception_exit(prev_state); \
185 return; \
186 } \
187 conditional_sti(regs); \
188 do_trap(trapnr, signr, str, regs, error_code, NULL); \
189 exception_exit(prev_state); \
190}
191
192#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \
193dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \
194{ \
195 siginfo_t info; \
196 enum ctx_state prev_state; \
197 \
198 info.si_signo = signr; \
199 info.si_errno = 0; \
200 info.si_code = sicode; \
201 info.si_addr = (void __user *)siaddr; \
202 prev_state = exception_enter(); \
203 if (notify_die(DIE_TRAP, str, regs, error_code, \
204 trapnr, signr) == NOTIFY_STOP) { \
205 exception_exit(prev_state); \
206 return; \
207 } \
208 conditional_sti(regs); \
209 do_trap(trapnr, signr, str, regs, error_code, &info); \
210 exception_exit(prev_state); \
211}
212
213DO_ERROR_INFO(X86_TRAP_DE, SIGFPE, "divide error", divide_error, FPE_INTDIV,
214 regs->ip)
215DO_ERROR(X86_TRAP_OF, SIGSEGV, "overflow", overflow)
216DO_ERROR(X86_TRAP_BR, SIGSEGV, "bounds", bounds)
217DO_ERROR_INFO(X86_TRAP_UD, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN,
218 regs->ip)
219DO_ERROR(X86_TRAP_OLD_MF, SIGFPE, "coprocessor segment overrun",
220 coprocessor_segment_overrun)
221DO_ERROR(X86_TRAP_TS, SIGSEGV, "invalid TSS", invalid_TSS)
222DO_ERROR(X86_TRAP_NP, SIGBUS, "segment not present", segment_not_present)
223#ifdef CONFIG_X86_32
224DO_ERROR(X86_TRAP_SS, SIGBUS, "stack segment", stack_segment)
225#endif
226DO_ERROR_INFO(X86_TRAP_AC, SIGBUS, "alignment check", alignment_check,
227 BUS_ADRALN, 0)
228
229#ifdef CONFIG_X86_64
230
231dotraplinkage void do_stack_segment(struct pt_regs *regs, long error_code)
232{
233 enum ctx_state prev_state;
234
235 prev_state = exception_enter();
236 if (notify_die(DIE_TRAP, "stack segment", regs, error_code,
237 X86_TRAP_SS, SIGBUS) != NOTIFY_STOP) {
238 preempt_conditional_sti(regs);
239 do_trap(X86_TRAP_SS, SIGBUS, "stack segment", regs, error_code, NULL);
240 preempt_conditional_cli(regs);
241 }
242 exception_exit(prev_state);
243}
244
245dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code)
246{
247 static const char str[] = "double fault";
248 struct task_struct *tsk = current;
249
250 exception_enter();
251
252 notify_die(DIE_TRAP, str, regs, error_code, X86_TRAP_DF, SIGSEGV);
253
254 tsk->thread.error_code = error_code;
255 tsk->thread.trap_nr = X86_TRAP_DF;
256
257
258
259
260
261 for (;;)
262 die(str, regs, error_code);
263}
264#endif
265
266dotraplinkage void __kprobes
267do_general_protection(struct pt_regs *regs, long error_code)
268{
269 struct task_struct *tsk;
270 enum ctx_state prev_state;
271
272 prev_state = exception_enter();
273 conditional_sti(regs);
274
275#ifdef CONFIG_X86_32
276 if (regs->flags & X86_VM_MASK) {
277 local_irq_enable();
278 handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code);
279 goto exit;
280 }
281#endif
282
283 tsk = current;
284 if (!user_mode(regs)) {
285 if (fixup_exception(regs))
286 goto exit;
287
288 tsk->thread.error_code = error_code;
289 tsk->thread.trap_nr = X86_TRAP_GP;
290 if (notify_die(DIE_GPF, "general protection fault", regs, error_code,
291 X86_TRAP_GP, SIGSEGV) != NOTIFY_STOP)
292 die("general protection fault", regs, error_code);
293 goto exit;
294 }
295
296 tsk->thread.error_code = error_code;
297 tsk->thread.trap_nr = X86_TRAP_GP;
298
299 if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
300 printk_ratelimit()) {
301 pr_info("%s[%d] general protection ip:%lx sp:%lx error:%lx",
302 tsk->comm, task_pid_nr(tsk),
303 regs->ip, regs->sp, error_code);
304 print_vma_addr(" in ", regs->ip);
305 pr_cont("\n");
306 }
307
308 force_sig(SIGSEGV, tsk);
309exit:
310 exception_exit(prev_state);
311}
312
313
314dotraplinkage void __kprobes notrace do_int3(struct pt_regs *regs, long error_code)
315{
316 enum ctx_state prev_state;
317
318#ifdef CONFIG_DYNAMIC_FTRACE
319
320
321
322
323 if (unlikely(atomic_read(&modifying_ftrace_code)) &&
324 ftrace_int3_handler(regs))
325 return;
326#endif
327 prev_state = exception_enter();
328#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
329 if (kgdb_ll_trap(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP,
330 SIGTRAP) == NOTIFY_STOP)
331 goto exit;
332#endif
333
334 if (notify_die(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP,
335 SIGTRAP) == NOTIFY_STOP)
336 goto exit;
337
338
339
340
341
342 debug_stack_usage_inc();
343 preempt_conditional_sti(regs);
344 do_trap(X86_TRAP_BP, SIGTRAP, "int3", regs, error_code, NULL);
345 preempt_conditional_cli(regs);
346 debug_stack_usage_dec();
347exit:
348 exception_exit(prev_state);
349}
350
351#ifdef CONFIG_X86_64
352
353
354
355
356
357asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs)
358{
359 struct pt_regs *regs = eregs;
360
361 if (eregs == (struct pt_regs *)eregs->sp)
362 ;
363
364 else if (user_mode(eregs))
365 regs = task_pt_regs(current);
366
367
368
369
370 else if (eregs->flags & X86_EFLAGS_IF)
371 regs = (struct pt_regs *)(eregs->sp -= sizeof(struct pt_regs));
372 if (eregs != regs)
373 *regs = *eregs;
374 return regs;
375}
376#endif
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
403{
404 struct task_struct *tsk = current;
405 enum ctx_state prev_state;
406 int user_icebp = 0;
407 unsigned long dr6;
408 int si_code;
409
410 prev_state = exception_enter();
411
412 get_debugreg(dr6, 6);
413
414
415 dr6 &= ~DR6_RESERVED;
416
417
418
419
420
421
422 if (!dr6 && user_mode(regs))
423 user_icebp = 1;
424
425
426 if ((dr6 & DR_STEP) && kmemcheck_trap(regs))
427 goto exit;
428
429
430 set_debugreg(0, 6);
431
432
433
434
435 clear_tsk_thread_flag(tsk, TIF_BLOCKSTEP);
436
437
438 tsk->thread.debugreg6 = dr6;
439
440 if (notify_die(DIE_DEBUG, "debug", regs, PTR_ERR(&dr6), error_code,
441 SIGTRAP) == NOTIFY_STOP)
442 goto exit;
443
444
445
446
447
448 debug_stack_usage_inc();
449
450
451 preempt_conditional_sti(regs);
452
453 if (regs->flags & X86_VM_MASK) {
454 handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code,
455 X86_TRAP_DB);
456 preempt_conditional_cli(regs);
457 debug_stack_usage_dec();
458 goto exit;
459 }
460
461
462
463
464
465
466
467
468 if ((dr6 & DR_STEP) && !user_mode(regs)) {
469 tsk->thread.debugreg6 &= ~DR_STEP;
470 set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
471 regs->flags &= ~X86_EFLAGS_TF;
472 }
473 si_code = get_si_code(tsk->thread.debugreg6);
474 if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS) || user_icebp)
475 send_sigtrap(tsk, regs, error_code, si_code);
476 preempt_conditional_cli(regs);
477 debug_stack_usage_dec();
478
479exit:
480 exception_exit(prev_state);
481}
482
483
484
485
486
487
488void math_error(struct pt_regs *regs, int error_code, int trapnr)
489{
490 struct task_struct *task = current;
491 siginfo_t info;
492 unsigned short err;
493 char *str = (trapnr == X86_TRAP_MF) ? "fpu exception" :
494 "simd exception";
495
496 if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, SIGFPE) == NOTIFY_STOP)
497 return;
498 conditional_sti(regs);
499
500 if (!user_mode_vm(regs))
501 {
502 if (!fixup_exception(regs)) {
503 task->thread.error_code = error_code;
504 task->thread.trap_nr = trapnr;
505 die(str, regs, error_code);
506 }
507 return;
508 }
509
510
511
512
513 save_init_fpu(task);
514 task->thread.trap_nr = trapnr;
515 task->thread.error_code = error_code;
516 info.si_signo = SIGFPE;
517 info.si_errno = 0;
518 info.si_addr = (void __user *)regs->ip;
519 if (trapnr == X86_TRAP_MF) {
520 unsigned short cwd, swd;
521
522
523
524
525
526
527
528
529
530
531 cwd = get_fpu_cwd(task);
532 swd = get_fpu_swd(task);
533
534 err = swd & ~cwd;
535 } else {
536
537
538
539
540
541
542 unsigned short mxcsr = get_fpu_mxcsr(task);
543 err = ~(mxcsr >> 7) & mxcsr;
544 }
545
546 if (err & 0x001) {
547
548
549
550
551
552 info.si_code = FPE_FLTINV;
553 } else if (err & 0x004) {
554 info.si_code = FPE_FLTDIV;
555 } else if (err & 0x008) {
556 info.si_code = FPE_FLTOVF;
557 } else if (err & 0x012) {
558 info.si_code = FPE_FLTUND;
559 } else if (err & 0x020) {
560 info.si_code = FPE_FLTRES;
561 } else {
562
563
564
565
566
567 return;
568 }
569 force_sig_info(SIGFPE, &info, task);
570}
571
572dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code)
573{
574 enum ctx_state prev_state;
575
576 prev_state = exception_enter();
577 math_error(regs, error_code, X86_TRAP_MF);
578 exception_exit(prev_state);
579}
580
581dotraplinkage void
582do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
583{
584 enum ctx_state prev_state;
585
586 prev_state = exception_enter();
587 math_error(regs, error_code, X86_TRAP_XF);
588 exception_exit(prev_state);
589}
590
591dotraplinkage void
592do_spurious_interrupt_bug(struct pt_regs *regs, long error_code)
593{
594 conditional_sti(regs);
595#if 0
596
597 pr_info("Ignoring P6 Local APIC Spurious Interrupt Bug...\n");
598#endif
599}
600
601asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void)
602{
603}
604
605asmlinkage void __attribute__((weak)) smp_threshold_interrupt(void)
606{
607}
608
609
610
611
612
613
614
615
616
617
618
619void math_state_restore(void)
620{
621 struct task_struct *tsk = current;
622
623 if (!tsk_used_math(tsk)) {
624 local_irq_enable();
625
626
627
628 if (init_fpu(tsk)) {
629
630
631
632 do_group_exit(SIGKILL);
633 return;
634 }
635 local_irq_disable();
636 }
637
638 __thread_fpu_begin(tsk);
639
640
641
642
643 if (unlikely(restore_fpu_checking(tsk))) {
644 drop_init_fpu(tsk);
645 force_sig(SIGSEGV, tsk);
646 return;
647 }
648
649 tsk->fpu_counter++;
650}
651EXPORT_SYMBOL_GPL(math_state_restore);
652
653dotraplinkage void __kprobes
654do_device_not_available(struct pt_regs *regs, long error_code)
655{
656 enum ctx_state prev_state;
657
658 prev_state = exception_enter();
659 BUG_ON(use_eager_fpu());
660
661#ifdef CONFIG_MATH_EMULATION
662 if (read_cr0() & X86_CR0_EM) {
663 struct math_emu_info info = { };
664
665 conditional_sti(regs);
666
667 info.regs = regs;
668 math_emulate(&info);
669 exception_exit(prev_state);
670 return;
671 }
672#endif
673 math_state_restore();
674#ifdef CONFIG_X86_32
675 conditional_sti(regs);
676#endif
677 exception_exit(prev_state);
678}
679
680#ifdef CONFIG_X86_32
681dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code)
682{
683 siginfo_t info;
684 enum ctx_state prev_state;
685
686 prev_state = exception_enter();
687 local_irq_enable();
688
689 info.si_signo = SIGILL;
690 info.si_errno = 0;
691 info.si_code = ILL_BADSTK;
692 info.si_addr = NULL;
693 if (notify_die(DIE_TRAP, "iret exception", regs, error_code,
694 X86_TRAP_IRET, SIGILL) != NOTIFY_STOP) {
695 do_trap(X86_TRAP_IRET, SIGILL, "iret exception", regs, error_code,
696 &info);
697 }
698 exception_exit(prev_state);
699}
700#endif
701
702
703void __init early_trap_init(void)
704{
705 set_intr_gate_ist(X86_TRAP_DB, &debug, DEBUG_STACK);
706
707 set_system_intr_gate_ist(X86_TRAP_BP, &int3, DEBUG_STACK);
708#ifdef CONFIG_X86_32
709 set_intr_gate(X86_TRAP_PF, &page_fault);
710#endif
711 load_idt(&idt_descr);
712}
713
714void __init early_trap_pf_init(void)
715{
716#ifdef CONFIG_X86_64
717 set_intr_gate(X86_TRAP_PF, &page_fault);
718#endif
719}
720
721void __init trap_init(void)
722{
723 int i;
724
725#ifdef CONFIG_EISA
726 void __iomem *p = early_ioremap(0x0FFFD9, 4);
727
728 if (readl(p) == 'E' + ('I'<<8) + ('S'<<16) + ('A'<<24))
729 EISA_bus = 1;
730 early_iounmap(p, 4);
731#endif
732
733 set_intr_gate(X86_TRAP_DE, ÷_error);
734 set_intr_gate_ist(X86_TRAP_NMI, &nmi, NMI_STACK);
735
736 set_system_intr_gate(X86_TRAP_OF, &overflow);
737 set_intr_gate(X86_TRAP_BR, &bounds);
738 set_intr_gate(X86_TRAP_UD, &invalid_op);
739 set_intr_gate(X86_TRAP_NM, &device_not_available);
740#ifdef CONFIG_X86_32
741 set_task_gate(X86_TRAP_DF, GDT_ENTRY_DOUBLEFAULT_TSS);
742#else
743 set_intr_gate_ist(X86_TRAP_DF, &double_fault, DOUBLEFAULT_STACK);
744#endif
745 set_intr_gate(X86_TRAP_OLD_MF, &coprocessor_segment_overrun);
746 set_intr_gate(X86_TRAP_TS, &invalid_TSS);
747 set_intr_gate(X86_TRAP_NP, &segment_not_present);
748 set_intr_gate_ist(X86_TRAP_SS, &stack_segment, STACKFAULT_STACK);
749 set_intr_gate(X86_TRAP_GP, &general_protection);
750 set_intr_gate(X86_TRAP_SPURIOUS, &spurious_interrupt_bug);
751 set_intr_gate(X86_TRAP_MF, &coprocessor_error);
752 set_intr_gate(X86_TRAP_AC, &alignment_check);
753#ifdef CONFIG_X86_MCE
754 set_intr_gate_ist(X86_TRAP_MC, &machine_check, MCE_STACK);
755#endif
756 set_intr_gate(X86_TRAP_XF, &simd_coprocessor_error);
757
758
759 for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++)
760 set_bit(i, used_vectors);
761
762#ifdef CONFIG_IA32_EMULATION
763 set_system_intr_gate(IA32_SYSCALL_VECTOR, ia32_syscall);
764 set_bit(IA32_SYSCALL_VECTOR, used_vectors);
765#endif
766
767#ifdef CONFIG_X86_32
768 set_system_trap_gate(SYSCALL_VECTOR, &system_call);
769 set_bit(SYSCALL_VECTOR, used_vectors);
770#endif
771
772
773
774
775
776
777 __set_fixmap(FIX_RO_IDT, __pa_symbol(idt_table), PAGE_KERNEL_RO);
778 idt_descr.address = fix_to_virt(FIX_RO_IDT);
779
780
781
782
783 cpu_init();
784
785 x86_init.irqs.trap_init();
786
787#ifdef CONFIG_X86_64
788 memcpy(&nmi_idt_table, &idt_table, IDT_ENTRIES * 16);
789 set_nmi_gate(X86_TRAP_DB, &debug);
790 set_nmi_gate(X86_TRAP_BP, &int3);
791#endif
792}
793