1 /* 2 * S390 version 3 * Copyright IBM Corp. 1999, 2000 4 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), 5 * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), 6 * 7 * Derived from "arch/i386/kernel/traps.c" 8 * Copyright (C) 1991, 1992 Linus Torvalds 9 */ 10 11 /* 12 * 'Traps.c' handles hardware traps and faults after we have saved some 13 * state in 'asm.s'. 14 */ 15 #include <linux/sched.h> 16 #include <linux/kernel.h> 17 #include <linux/string.h> 18 #include <linux/errno.h> 19 #include <linux/ptrace.h> 20 #include <linux/timer.h> 21 #include <linux/mm.h> 22 #include <linux/smp.h> 23 #include <linux/init.h> 24 #include <linux/interrupt.h> 25 #include <linux/seq_file.h> 26 #include <linux/delay.h> 27 #include <linux/module.h> 28 #include <linux/kdebug.h> 29 #include <linux/kallsyms.h> 30 #include <linux/reboot.h> 31 #include <linux/kprobes.h> 32 #include <linux/bug.h> 33 #include <linux/utsname.h> 34 #include <asm/uaccess.h> 35 #include <asm/io.h> 36 #include <linux/atomic.h> 37 #include <asm/mathemu.h> 38 #include <asm/cpcmd.h> 39 #include <asm/lowcore.h> 40 #include <asm/debug.h> 41 #include <asm/ipl.h> 42 #include "entry.h" 43 44 int show_unhandled_signals = 1; 45 46 #define stack_pointer ({ void **sp; asm("la %0,0(15)" : "=&d" (sp)); sp; }) 47 48 #ifndef CONFIG_64BIT 49 #define LONG "%08lx " 50 #define FOURLONG "%08lx %08lx %08lx %08lx\n" 51 static int kstack_depth_to_print = 12; 52 #else /* CONFIG_64BIT */ 53 #define LONG "%016lx " 54 #define FOURLONG "%016lx %016lx %016lx %016lx\n" 55 static int kstack_depth_to_print = 20; 56 #endif /* CONFIG_64BIT */ 57 58 static inline void __user *get_trap_ip(struct pt_regs *regs) 59 { 60 #ifdef CONFIG_64BIT 61 unsigned long address; 62 63 if (regs->int_code & 0x200) 64 address = *(unsigned long *)(current->thread.trap_tdb + 24); 65 else 66 address = regs->psw.addr; 67 return (void __user *) 68 ((address - (regs->int_code >> 16)) & PSW_ADDR_INSN); 69 #else 70 return (void __user *) 71 ((regs->psw.addr - (regs->int_code >> 16)) & PSW_ADDR_INSN); 72 #endif 73 } 74 75 /* 76 * For show_trace we have tree different stack to consider: 77 * - the panic stack which is used if the kernel stack has overflown 78 * - the asynchronous interrupt stack (cpu related) 79 * - the synchronous kernel stack (process related) 80 * The stack trace can start at any of the three stack and can potentially 81 * touch all of them. The order is: panic stack, async stack, sync stack. 82 */ 83 static unsigned long 84 __show_trace(unsigned long sp, unsigned long low, unsigned long high) 85 { 86 struct stack_frame *sf; 87 struct pt_regs *regs; 88 89 while (1) { 90 sp = sp & PSW_ADDR_INSN; 91 if (sp < low || sp > high - sizeof(*sf)) 92 return sp; 93 sf = (struct stack_frame *) sp; 94 printk("([<%016lx>] ", sf->gprs[8] & PSW_ADDR_INSN); 95 print_symbol("%s)\n", sf->gprs[8] & PSW_ADDR_INSN); 96 /* Follow the backchain. */ 97 while (1) { 98 low = sp; 99 sp = sf->back_chain & PSW_ADDR_INSN; 100 if (!sp) 101 break; 102 if (sp <= low || sp > high - sizeof(*sf)) 103 return sp; 104 sf = (struct stack_frame *) sp; 105 printk(" [<%016lx>] ", sf->gprs[8] & PSW_ADDR_INSN); 106 print_symbol("%s\n", sf->gprs[8] & PSW_ADDR_INSN); 107 } 108 /* Zero backchain detected, check for interrupt frame. */ 109 sp = (unsigned long) (sf + 1); 110 if (sp <= low || sp > high - sizeof(*regs)) 111 return sp; 112 regs = (struct pt_regs *) sp; 113 printk(" [<%016lx>] ", regs->psw.addr & PSW_ADDR_INSN); 114 print_symbol("%s\n", regs->psw.addr & PSW_ADDR_INSN); 115 low = sp; 116 sp = regs->gprs[15]; 117 } 118 } 119 120 static void show_trace(struct task_struct *task, unsigned long *stack) 121 { 122 register unsigned long __r15 asm ("15"); 123 unsigned long sp; 124 125 sp = (unsigned long) stack; 126 if (!sp) 127 sp = task ? task->thread.ksp : __r15; 128 printk("Call Trace:\n"); 129 #ifdef CONFIG_CHECK_STACK 130 sp = __show_trace(sp, S390_lowcore.panic_stack - 4096, 131 S390_lowcore.panic_stack); 132 #endif 133 sp = __show_trace(sp, S390_lowcore.async_stack - ASYNC_SIZE, 134 S390_lowcore.async_stack); 135 if (task) 136 __show_trace(sp, (unsigned long) task_stack_page(task), 137 (unsigned long) task_stack_page(task) + THREAD_SIZE); 138 else 139 __show_trace(sp, S390_lowcore.thread_info, 140 S390_lowcore.thread_info + THREAD_SIZE); 141 if (!task) 142 task = current; 143 debug_show_held_locks(task); 144 } 145 146 void show_stack(struct task_struct *task, unsigned long *sp) 147 { 148 register unsigned long * __r15 asm ("15"); 149 unsigned long *stack; 150 int i; 151 152 if (!sp) 153 stack = task ? (unsigned long *) task->thread.ksp : __r15; 154 else 155 stack = sp; 156 157 for (i = 0; i < kstack_depth_to_print; i++) { 158 if (((addr_t) stack & (THREAD_SIZE-1)) == 0) 159 break; 160 if ((i * sizeof(long) % 32) == 0) 161 printk("%s ", i == 0 ? "" : "\n"); 162 printk(LONG, *stack++); 163 } 164 printk("\n"); 165 show_trace(task, sp); 166 } 167 168 static void show_last_breaking_event(struct pt_regs *regs) 169 { 170 #ifdef CONFIG_64BIT 171 printk("Last Breaking-Event-Address:\n"); 172 printk(" [<%016lx>] ", regs->args[0] & PSW_ADDR_INSN); 173 print_symbol("%s\n", regs->args[0] & PSW_ADDR_INSN); 174 #endif 175 } 176 177 /* 178 * The architecture-independent dump_stack generator 179 */ 180 void dump_stack(void) 181 { 182 printk("CPU: %d %s %s %.*s\n", 183 task_thread_info(current)->cpu, print_tainted(), 184 init_utsname()->release, 185 (int)strcspn(init_utsname()->version, " "), 186 init_utsname()->version); 187 printk("Process %s (pid: %d, task: %p, ksp: %p)\n", 188 current->comm, current->pid, current, 189 (void *) current->thread.ksp); 190 show_stack(NULL, NULL); 191 } 192 EXPORT_SYMBOL(dump_stack); 193 194 static inline int mask_bits(struct pt_regs *regs, unsigned long bits) 195 { 196 return (regs->psw.mask & bits) / ((~bits + 1) & bits); 197 } 198 199 void show_registers(struct pt_regs *regs) 200 { 201 char *mode; 202 203 mode = user_mode(regs) ? "User" : "Krnl"; 204 printk("%s PSW : %p %p", 205 mode, (void *) regs->psw.mask, 206 (void *) regs->psw.addr); 207 print_symbol(" (%s)\n", regs->psw.addr & PSW_ADDR_INSN); 208 printk(" R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x " 209 "P:%x AS:%x CC:%x PM:%x", mask_bits(regs, PSW_MASK_PER), 210 mask_bits(regs, PSW_MASK_DAT), mask_bits(regs, PSW_MASK_IO), 211 mask_bits(regs, PSW_MASK_EXT), mask_bits(regs, PSW_MASK_KEY), 212 mask_bits(regs, PSW_MASK_MCHECK), mask_bits(regs, PSW_MASK_WAIT), 213 mask_bits(regs, PSW_MASK_PSTATE), mask_bits(regs, PSW_MASK_ASC), 214 mask_bits(regs, PSW_MASK_CC), mask_bits(regs, PSW_MASK_PM)); 215 #ifdef CONFIG_64BIT 216 printk(" EA:%x", mask_bits(regs, PSW_MASK_EA | PSW_MASK_BA)); 217 #endif 218 printk("\n%s GPRS: " FOURLONG, mode, 219 regs->gprs[0], regs->gprs[1], regs->gprs[2], regs->gprs[3]); 220 printk(" " FOURLONG, 221 regs->gprs[4], regs->gprs[5], regs->gprs[6], regs->gprs[7]); 222 printk(" " FOURLONG, 223 regs->gprs[8], regs->gprs[9], regs->gprs[10], regs->gprs[11]); 224 printk(" " FOURLONG, 225 regs->gprs[12], regs->gprs[13], regs->gprs[14], regs->gprs[15]); 226 227 show_code(regs); 228 } 229 230 void show_regs(struct pt_regs *regs) 231 { 232 printk("CPU: %d %s %s %.*s\n", 233 task_thread_info(current)->cpu, print_tainted(), 234 init_utsname()->release, 235 (int)strcspn(init_utsname()->version, " "), 236 init_utsname()->version); 237 printk("Process %s (pid: %d, task: %p, ksp: %p)\n", 238 current->comm, current->pid, current, 239 (void *) current->thread.ksp); 240 show_registers(regs); 241 /* Show stack backtrace if pt_regs is from kernel mode */ 242 if (!user_mode(regs)) 243 show_trace(NULL, (unsigned long *) regs->gprs[15]); 244 show_last_breaking_event(regs); 245 } 246 247 static DEFINE_SPINLOCK(die_lock); 248 249 void die(struct pt_regs *regs, const char *str) 250 { 251 static int die_counter; 252 253 oops_enter(); 254 lgr_info_log(); 255 debug_stop_all(); 256 console_verbose(); 257 spin_lock_irq(&die_lock); 258 bust_spinlocks(1); 259 printk("%s: %04x [#%d] ", str, regs->int_code & 0xffff, ++die_counter); 260 #ifdef CONFIG_PREEMPT 261 printk("PREEMPT "); 262 #endif 263 #ifdef CONFIG_SMP 264 printk("SMP "); 265 #endif 266 #ifdef CONFIG_DEBUG_PAGEALLOC 267 printk("DEBUG_PAGEALLOC"); 268 #endif 269 printk("\n"); 270 notify_die(DIE_OOPS, str, regs, 0, regs->int_code & 0xffff, SIGSEGV); 271 print_modules(); 272 show_regs(regs); 273 bust_spinlocks(0); 274 add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); 275 spin_unlock_irq(&die_lock); 276 if (in_interrupt()) 277 panic("Fatal exception in interrupt"); 278 if (panic_on_oops) 279 panic("Fatal exception: panic_on_oops"); 280 oops_exit(); 281 do_exit(SIGSEGV); 282 } 283 284 static inline void report_user_fault(struct pt_regs *regs, int signr) 285 { 286 if ((task_pid_nr(current) > 1) && !show_unhandled_signals) 287 return; 288 if (!unhandled_signal(current, signr)) 289 return; 290 if (!printk_ratelimit()) 291 return; 292 printk("User process fault: interruption code 0x%X ", regs->int_code); 293 print_vma_addr("in ", regs->psw.addr & PSW_ADDR_INSN); 294 printk("\n"); 295 show_regs(regs); 296 } 297 298 int is_valid_bugaddr(unsigned long addr) 299 { 300 return 1; 301 } 302 303 static void __kprobes do_trap(struct pt_regs *regs, 304 int si_signo, int si_code, char *str) 305 { 306 siginfo_t info; 307 308 if (notify_die(DIE_TRAP, str, regs, 0, 309 regs->int_code, si_signo) == NOTIFY_STOP) 310 return; 311 312 if (user_mode(regs)) { 313 info.si_signo = si_signo; 314 info.si_errno = 0; 315 info.si_code = si_code; 316 info.si_addr = get_trap_ip(regs); 317 force_sig_info(si_signo, &info, current); 318 report_user_fault(regs, si_signo); 319 } else { 320 const struct exception_table_entry *fixup; 321 fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN); 322 if (fixup) 323 regs->psw.addr = extable_fixup(fixup) | PSW_ADDR_AMODE; 324 else { 325 enum bug_trap_type btt; 326 327 btt = report_bug(regs->psw.addr & PSW_ADDR_INSN, regs); 328 if (btt == BUG_TRAP_TYPE_WARN) 329 return; 330 die(regs, str); 331 } 332 } 333 } 334 335 void __kprobes do_per_trap(struct pt_regs *regs) 336 { 337 siginfo_t info; 338 339 if (notify_die(DIE_SSTEP, "sstep", regs, 0, 0, SIGTRAP) == NOTIFY_STOP) 340 return; 341 if (!current->ptrace) 342 return; 343 info.si_signo = SIGTRAP; 344 info.si_errno = 0; 345 info.si_code = TRAP_HWBKPT; 346 info.si_addr = 347 (void __force __user *) current->thread.per_event.address; 348 force_sig_info(SIGTRAP, &info, current); 349 } 350 351 void default_trap_handler(struct pt_regs *regs) 352 { 353 if (user_mode(regs)) { 354 report_user_fault(regs, SIGSEGV); 355 do_exit(SIGSEGV); 356 } else 357 die(regs, "Unknown program exception"); 358 } 359 360 #define DO_ERROR_INFO(name, signr, sicode, str) \ 361 void name(struct pt_regs *regs) \ 362 { \ 363 do_trap(regs, signr, sicode, str); \ 364 } 365 366 DO_ERROR_INFO(addressing_exception, SIGILL, ILL_ILLADR, 367 "addressing exception") 368 DO_ERROR_INFO(execute_exception, SIGILL, ILL_ILLOPN, 369 "execute exception") 370 DO_ERROR_INFO(divide_exception, SIGFPE, FPE_INTDIV, 371 "fixpoint divide exception") 372 DO_ERROR_INFO(overflow_exception, SIGFPE, FPE_INTOVF, 373 "fixpoint overflow exception") 374 DO_ERROR_INFO(hfp_overflow_exception, SIGFPE, FPE_FLTOVF, 375 "HFP overflow exception") 376 DO_ERROR_INFO(hfp_underflow_exception, SIGFPE, FPE_FLTUND, 377 "HFP underflow exception") 378 DO_ERROR_INFO(hfp_significance_exception, SIGFPE, FPE_FLTRES, 379 "HFP significance exception") 380 DO_ERROR_INFO(hfp_divide_exception, SIGFPE, FPE_FLTDIV, 381 "HFP divide exception") 382 DO_ERROR_INFO(hfp_sqrt_exception, SIGFPE, FPE_FLTINV, 383 "HFP square root exception") 384 DO_ERROR_INFO(operand_exception, SIGILL, ILL_ILLOPN, 385 "operand exception") 386 DO_ERROR_INFO(privileged_op, SIGILL, ILL_PRVOPC, 387 "privileged operation") 388 DO_ERROR_INFO(special_op_exception, SIGILL, ILL_ILLOPN, 389 "special operation exception") 390 DO_ERROR_INFO(translation_exception, SIGILL, ILL_ILLOPN, 391 "translation exception") 392 393 #ifdef CONFIG_64BIT 394 DO_ERROR_INFO(transaction_exception, SIGILL, ILL_ILLOPN, 395 "transaction constraint exception") 396 #endif 397 398 static inline void do_fp_trap(struct pt_regs *regs, int fpc) 399 { 400 int si_code = 0; 401 /* FPC[2] is Data Exception Code */ 402 if ((fpc & 0x00000300) == 0) { 403 /* bits 6 and 7 of DXC are 0 iff IEEE exception */ 404 if (fpc & 0x8000) /* invalid fp operation */ 405 si_code = FPE_FLTINV; 406 else if (fpc & 0x4000) /* div by 0 */ 407 si_code = FPE_FLTDIV; 408 else if (fpc & 0x2000) /* overflow */ 409 si_code = FPE_FLTOVF; 410 else if (fpc & 0x1000) /* underflow */ 411 si_code = FPE_FLTUND; 412 else if (fpc & 0x0800) /* inexact */ 413 si_code = FPE_FLTRES; 414 } 415 do_trap(regs, SIGFPE, si_code, "floating point exception"); 416 } 417 418 void __kprobes illegal_op(struct pt_regs *regs) 419 { 420 siginfo_t info; 421 __u8 opcode[6]; 422 __u16 __user *location; 423 int signal = 0; 424 425 location = get_trap_ip(regs); 426 427 if (user_mode(regs)) { 428 if (get_user(*((__u16 *) opcode), (__u16 __user *) location)) 429 return; 430 if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) { 431 if (current->ptrace) { 432 info.si_signo = SIGTRAP; 433 info.si_errno = 0; 434 info.si_code = TRAP_BRKPT; 435 info.si_addr = location; 436 force_sig_info(SIGTRAP, &info, current); 437 } else 438 signal = SIGILL; 439 #ifdef CONFIG_MATHEMU 440 } else if (opcode[0] == 0xb3) { 441 if (get_user(*((__u16 *) (opcode+2)), location+1)) 442 return; 443 signal = math_emu_b3(opcode, regs); 444 } else if (opcode[0] == 0xed) { 445 if (get_user(*((__u32 *) (opcode+2)), 446 (__u32 __user *)(location+1))) 447 return; 448 signal = math_emu_ed(opcode, regs); 449 } else if (*((__u16 *) opcode) == 0xb299) { 450 if (get_user(*((__u16 *) (opcode+2)), location+1)) 451 return; 452 signal = math_emu_srnm(opcode, regs); 453 } else if (*((__u16 *) opcode) == 0xb29c) { 454 if (get_user(*((__u16 *) (opcode+2)), location+1)) 455 return; 456 signal = math_emu_stfpc(opcode, regs); 457 } else if (*((__u16 *) opcode) == 0xb29d) { 458 if (get_user(*((__u16 *) (opcode+2)), location+1)) 459 return; 460 signal = math_emu_lfpc(opcode, regs); 461 #endif 462 } else 463 signal = SIGILL; 464 } else { 465 /* 466 * If we get an illegal op in kernel mode, send it through the 467 * kprobes notifier. If kprobes doesn't pick it up, SIGILL 468 */ 469 if (notify_die(DIE_BPT, "bpt", regs, 0, 470 3, SIGTRAP) != NOTIFY_STOP) 471 signal = SIGILL; 472 } 473 474 #ifdef CONFIG_MATHEMU 475 if (signal == SIGFPE) 476 do_fp_trap(regs, current->thread.fp_regs.fpc); 477 else if (signal == SIGSEGV) 478 do_trap(regs, signal, SEGV_MAPERR, "user address fault"); 479 else 480 #endif 481 if (signal) 482 do_trap(regs, signal, ILL_ILLOPC, "illegal operation"); 483 } 484 485 486 #ifdef CONFIG_MATHEMU 487 void specification_exception(struct pt_regs *regs) 488 { 489 __u8 opcode[6]; 490 __u16 __user *location = NULL; 491 int signal = 0; 492 493 location = (__u16 __user *) get_trap_ip(regs); 494 495 if (user_mode(regs)) { 496 get_user(*((__u16 *) opcode), location); 497 switch (opcode[0]) { 498 case 0x28: /* LDR Rx,Ry */ 499 signal = math_emu_ldr(opcode); 500 break; 501 case 0x38: /* LER Rx,Ry */ 502 signal = math_emu_ler(opcode); 503 break; 504 case 0x60: /* STD R,D(X,B) */ 505 get_user(*((__u16 *) (opcode+2)), location+1); 506 signal = math_emu_std(opcode, regs); 507 break; 508 case 0x68: /* LD R,D(X,B) */ 509 get_user(*((__u16 *) (opcode+2)), location+1); 510 signal = math_emu_ld(opcode, regs); 511 break; 512 case 0x70: /* STE R,D(X,B) */ 513 get_user(*((__u16 *) (opcode+2)), location+1); 514 signal = math_emu_ste(opcode, regs); 515 break; 516 case 0x78: /* LE R,D(X,B) */ 517 get_user(*((__u16 *) (opcode+2)), location+1); 518 signal = math_emu_le(opcode, regs); 519 break; 520 default: 521 signal = SIGILL; 522 break; 523 } 524 } else 525 signal = SIGILL; 526 527 if (signal == SIGFPE) 528 do_fp_trap(regs, current->thread.fp_regs.fpc); 529 else if (signal) 530 do_trap(regs, signal, ILL_ILLOPN, "specification exception"); 531 } 532 #else 533 DO_ERROR_INFO(specification_exception, SIGILL, ILL_ILLOPN, 534 "specification exception"); 535 #endif 536 537 void data_exception(struct pt_regs *regs) 538 { 539 __u16 __user *location; 540 int signal = 0; 541 542 location = get_trap_ip(regs); 543 544 if (MACHINE_HAS_IEEE) 545 asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc)); 546 547 #ifdef CONFIG_MATHEMU 548 else if (user_mode(regs)) { 549 __u8 opcode[6]; 550 get_user(*((__u16 *) opcode), location); 551 switch (opcode[0]) { 552 case 0x28: /* LDR Rx,Ry */ 553 signal = math_emu_ldr(opcode); 554 break; 555 case 0x38: /* LER Rx,Ry */ 556 signal = math_emu_ler(opcode); 557 break; 558 case 0x60: /* STD R,D(X,B) */ 559 get_user(*((__u16 *) (opcode+2)), location+1); 560 signal = math_emu_std(opcode, regs); 561 break; 562 case 0x68: /* LD R,D(X,B) */ 563 get_user(*((__u16 *) (opcode+2)), location+1); 564 signal = math_emu_ld(opcode, regs); 565 break; 566 case 0x70: /* STE R,D(X,B) */ 567 get_user(*((__u16 *) (opcode+2)), location+1); 568 signal = math_emu_ste(opcode, regs); 569 break; 570 case 0x78: /* LE R,D(X,B) */ 571 get_user(*((__u16 *) (opcode+2)), location+1); 572 signal = math_emu_le(opcode, regs); 573 break; 574 case 0xb3: 575 get_user(*((__u16 *) (opcode+2)), location+1); 576 signal = math_emu_b3(opcode, regs); 577 break; 578 case 0xed: 579 get_user(*((__u32 *) (opcode+2)), 580 (__u32 __user *)(location+1)); 581 signal = math_emu_ed(opcode, regs); 582 break; 583 case 0xb2: 584 if (opcode[1] == 0x99) { 585 get_user(*((__u16 *) (opcode+2)), location+1); 586 signal = math_emu_srnm(opcode, regs); 587 } else if (opcode[1] == 0x9c) { 588 get_user(*((__u16 *) (opcode+2)), location+1); 589 signal = math_emu_stfpc(opcode, regs); 590 } else if (opcode[1] == 0x9d) { 591 get_user(*((__u16 *) (opcode+2)), location+1); 592 signal = math_emu_lfpc(opcode, regs); 593 } else 594 signal = SIGILL; 595 break; 596 default: 597 signal = SIGILL; 598 break; 599 } 600 } 601 #endif 602 if (current->thread.fp_regs.fpc & FPC_DXC_MASK) 603 signal = SIGFPE; 604 else 605 signal = SIGILL; 606 if (signal == SIGFPE) 607 do_fp_trap(regs, current->thread.fp_regs.fpc); 608 else if (signal) 609 do_trap(regs, signal, ILL_ILLOPN, "data exception"); 610 } 611 612 void space_switch_exception(struct pt_regs *regs) 613 { 614 /* Set user psw back to home space mode. */ 615 if (user_mode(regs)) 616 regs->psw.mask |= PSW_ASC_HOME; 617 /* Send SIGILL. */ 618 do_trap(regs, SIGILL, ILL_PRVOPC, "space switch event"); 619 } 620 621 void __kprobes kernel_stack_overflow(struct pt_regs * regs) 622 { 623 bust_spinlocks(1); 624 printk("Kernel stack overflow.\n"); 625 show_regs(regs); 626 bust_spinlocks(0); 627 panic("Corrupt kernel stack, can't continue."); 628 } 629 630 void __init trap_init(void) 631 { 632 local_mcck_enable(); 633 } 634