Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
traps.c
Go to the documentation of this file.
1 /*
2  * Helper functions for trap handlers
3  *
4  * Copyright (C) 2000-2007, Axis Communications AB.
5  *
6  * Authors: Bjorn Wesen
7  * Hans-Peter Nilsson
8  *
9  */
10 
11 #include <linux/ptrace.h>
12 #include <asm/uaccess.h>
13 #include <arch/sv_addr_ag.h>
14 #include <arch/system.h>
15 
16 void
18 {
19  /*
20  * It's possible to use either the USP register or current->thread.usp.
21  * USP might not correspond to the current process for all cases this
22  * function is called, and current->thread.usp isn't up to date for the
23  * current process. Experience shows that using USP is the way to go.
24  */
25  unsigned long usp = rdusp();
26 
27  printk("IRP: %08lx SRP: %08lx DCCR: %08lx USP: %08lx MOF: %08lx\n",
28  regs->irp, regs->srp, regs->dccr, usp, regs->mof);
29 
30  printk(" r0: %08lx r1: %08lx r2: %08lx r3: %08lx\n",
31  regs->r0, regs->r1, regs->r2, regs->r3);
32 
33  printk(" r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n",
34  regs->r4, regs->r5, regs->r6, regs->r7);
35 
36  printk(" r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n",
37  regs->r8, regs->r9, regs->r10, regs->r11);
38 
39  printk("r12: %08lx r13: %08lx oR10: %08lx sp: %08lx\n",
40  regs->r12, regs->r13, regs->orig_r10, (long unsigned)regs);
41 
42  printk("R_MMU_CAUSE: %08lx\n", (unsigned long)*R_MMU_CAUSE);
43 
44  printk("Process %s (pid: %d, stackpage=%08lx)\n",
45  current->comm, current->pid, (unsigned long)current);
46 
47  /*
48  * When in-kernel, we also print out the stack and code at the
49  * time of the fault..
50  */
51  if (!user_mode(regs)) {
52  int i;
53 
54  show_stack(NULL, (unsigned long *)usp);
55 
56  /*
57  * If the previous stack-dump wasn't a kernel one, dump the
58  * kernel stack now.
59  */
60  if (usp != 0)
62 
63  printk("\nCode: ");
64 
65  if (regs->irp < PAGE_OFFSET)
66  goto bad_value;
67 
68  /*
69  * Quite often the value at regs->irp doesn't point to the
70  * interesting instruction, which often is the previous
71  * instruction. So dump at an offset large enough that the
72  * instruction decoding should be in sync at the interesting
73  * point, but small enough to fit on a row. The regs->irp
74  * location is pointed out in a ksymoops-friendly way by
75  * wrapping the byte for that address in parenthesises.
76  */
77  for (i = -12; i < 12; i++) {
78  unsigned char c;
79 
80  if (__get_user(c, &((unsigned char *)regs->irp)[i])) {
81 bad_value:
82  printk(" Bad IP value.");
83  break;
84  }
85 
86  if (i == 0)
87  printk("(%02x) ", c);
88  else
89  printk("%02x ", c);
90  }
91  printk("\n");
92  }
93 }
94 
95 void
97 {
98  asm volatile ("setf m");
99 }
100 
101 extern void (*nmi_handler)(struct pt_regs *);
102 void handle_nmi(struct pt_regs *regs)
103 {
104  if (nmi_handler)
105  nmi_handler(regs);
106 
107  /* Wait until nmi is no longer active. (We enable NMI immediately after
108  returning from this function, and we don't want it happening while
109  exiting from the NMI interrupt handler.) */
110  while (*R_IRQ_MASK0_RD & IO_STATE(R_IRQ_MASK0_RD, nmi_pin, active))
111  ;
112 }
113 
114 #ifdef CONFIG_DEBUG_BUGVERBOSE
115 void
116 handle_BUG(struct pt_regs *regs)
117 {
118  struct bug_frame f;
119  unsigned char c;
120  unsigned long irp = regs->irp;
121 
122  if (__copy_from_user(&f, (const void __user *)(irp - 8), sizeof f))
123  return;
124  if (f.prefix != BUG_PREFIX || f.magic != BUG_MAGIC)
125  return;
126  if (__get_user(c, f.filename))
127  f.filename = "<bad filename>";
128 
129  printk("kernel BUG at %s:%d!\n", f.filename, f.line);
130 }
131 #endif