Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
openrisc
kernel
traps.c
Go to the documentation of this file.
1
/*
2
* OpenRISC traps.c
3
*
4
* Linux architectural port borrowing liberally from similar works of
5
* others. All original copyrights apply as per the original source
6
* declaration.
7
*
8
* Modifications for the OpenRISC architecture:
9
* Copyright (C) 2003 Matjaz Breskvar <
[email protected]
>
10
* Copyright (C) 2010-2011 Jonas Bonn <
[email protected]
>
11
*
12
* This program is free software; you can redistribute it and/or
13
* modify it under the terms of the GNU General Public License
14
* as published by the Free Software Foundation; either version
15
* 2 of the License, or (at your option) any later version.
16
*
17
* Here we handle the break vectors not used by the system call
18
* mechanism, as well as some general stack/register dumping
19
* things.
20
*
21
*/
22
23
#include <
linux/init.h
>
24
#include <linux/sched.h>
25
#include <linux/kernel.h>
26
#include <linux/module.h>
27
#include <
linux/kmod.h
>
28
#include <linux/string.h>
29
#include <linux/errno.h>
30
#include <linux/ptrace.h>
31
#include <
linux/timer.h
>
32
#include <
linux/mm.h
>
33
#include <
linux/kallsyms.h
>
34
#include <asm/uaccess.h>
35
36
#include <asm/segment.h>
37
#include <asm/io.h>
38
#include <asm/pgtable.h>
39
40
extern
char
_etext
,
_stext
;
41
42
int
kstack_depth_to_print
= 0x180;
43
44
static
inline
int
valid_stack_ptr(
struct
thread_info
*
tinfo
,
void
*
p
)
45
{
46
return
p > (
void
*)tinfo && p < (
void
*)tinfo +
THREAD_SIZE
- 3;
47
}
48
49
void
show_trace
(
struct
task_struct
*
task
,
unsigned
long
*
stack
)
50
{
51
struct
thread_info
*
context
;
52
unsigned
long
addr
;
53
54
context = (
struct
thread_info
*)
55
((
unsigned
long
)stack & (~(
THREAD_SIZE
- 1)));
56
57
while
(valid_stack_ptr(context, stack)) {
58
addr = *stack++;
59
if
(
__kernel_text_address
(addr)) {
60
printk
(
" [<%08lx>]"
, addr);
61
print_symbol(
" %s"
, addr);
62
printk
(
"\n"
);
63
}
64
}
65
printk
(
" =======================\n"
);
66
}
67
68
/* displays a short stack trace */
69
void
show_stack
(
struct
task_struct
*
task
,
unsigned
long
*
esp
)
70
{
71
unsigned
long
addr
, *
stack
;
72
int
i
;
73
74
if
(esp ==
NULL
)
75
esp = (
unsigned
long
*)&esp;
76
77
stack = esp;
78
79
printk
(
"Stack dump [0x%08lx]:\n"
, (
unsigned
long
)esp);
80
for
(i = 0; i <
kstack_depth_to_print
; i++) {
81
if
(kstack_end(stack))
82
break
;
83
if
(
__get_user
(addr, stack)) {
84
/* This message matches "failing address" marked
85
s390 in ksymoops, so lines containing it will
86
not be filtered out by ksymoops. */
87
printk
(
"Failing address 0x%lx\n"
, (
unsigned
long
)stack);
88
break
;
89
}
90
stack++;
91
92
printk
(
"sp + %02d: 0x%08lx\n"
, i * 4, addr);
93
}
94
printk
(
"\n"
);
95
96
show_trace
(task, esp);
97
98
return
;
99
}
100
101
void
show_trace_task
(
struct
task_struct
*tsk)
102
{
103
/*
104
* TODO: SysRq-T trace dump...
105
*/
106
}
107
108
/*
109
* The architecture-independent backtrace generator
110
*/
111
void
dump_stack
(
void
)
112
{
113
unsigned
long
stack
;
114
115
show_stack
(
current
, &stack);
116
}
117
EXPORT_SYMBOL
(
dump_stack
);
118
119
void
show_registers
(
struct
pt_regs
*
regs
)
120
{
121
int
i
;
122
int
in_kernel = 1;
123
unsigned
long
esp
;
124
125
esp = (
unsigned
long
)(®s->
sp
);
126
if
(
user_mode
(regs))
127
in_kernel = 0;
128
129
printk
(
"CPU #: %d\n"
130
" PC: %08lx SR: %08lx SP: %08lx\n"
,
131
smp_processor_id
(), regs->
pc
, regs->
sr
, regs->
sp
);
132
printk
(
"GPR00: %08lx GPR01: %08lx GPR02: %08lx GPR03: %08lx\n"
,
133
0
L
, regs->
gpr
[1], regs->
gpr
[2], regs->
gpr
[3]);
134
printk
(
"GPR04: %08lx GPR05: %08lx GPR06: %08lx GPR07: %08lx\n"
,
135
regs->
gpr
[4], regs->
gpr
[5], regs->
gpr
[6], regs->
gpr
[7]);
136
printk
(
"GPR08: %08lx GPR09: %08lx GPR10: %08lx GPR11: %08lx\n"
,
137
regs->
gpr
[8], regs->
gpr
[9], regs->
gpr
[10], regs->
gpr
[11]);
138
printk
(
"GPR12: %08lx GPR13: %08lx GPR14: %08lx GPR15: %08lx\n"
,
139
regs->
gpr
[12], regs->
gpr
[13], regs->
gpr
[14], regs->
gpr
[15]);
140
printk
(
"GPR16: %08lx GPR17: %08lx GPR18: %08lx GPR19: %08lx\n"
,
141
regs->
gpr
[16], regs->
gpr
[17], regs->
gpr
[18], regs->
gpr
[19]);
142
printk
(
"GPR20: %08lx GPR21: %08lx GPR22: %08lx GPR23: %08lx\n"
,
143
regs->
gpr
[20], regs->
gpr
[21], regs->
gpr
[22], regs->
gpr
[23]);
144
printk
(
"GPR24: %08lx GPR25: %08lx GPR26: %08lx GPR27: %08lx\n"
,
145
regs->
gpr
[24], regs->
gpr
[25], regs->
gpr
[26], regs->
gpr
[27]);
146
printk
(
"GPR28: %08lx GPR29: %08lx GPR30: %08lx GPR31: %08lx\n"
,
147
regs->
gpr
[28], regs->
gpr
[29], regs->
gpr
[30], regs->
gpr
[31]);
148
printk
(
" RES: %08lx oGPR11: %08lx\n"
,
149
regs->
gpr
[11], regs->
orig_gpr11
);
150
151
printk
(
"Process %s (pid: %d, stackpage=%08lx)\n"
,
152
current
->comm,
current
->pid, (
unsigned
long
)
current
);
153
/*
154
* When in-kernel, we also print out the stack and code at the
155
* time of the fault..
156
*/
157
if
(in_kernel) {
158
159
printk
(
"\nStack: "
);
160
show_stack
(
NULL
, (
unsigned
long
*)esp);
161
162
printk
(
"\nCode: "
);
163
if
(regs->
pc
<
PAGE_OFFSET
)
164
goto
bad
;
165
166
for
(i = -24; i < 24; i++) {
167
unsigned
char
c
;
168
if
(
__get_user
(c, &((
unsigned
char
*)regs->
pc
)[i])) {
169
bad
:
170
printk
(
" Bad PC value."
);
171
break
;
172
}
173
174
if
(i == 0)
175
printk
(
"(%02x) "
, c);
176
else
177
printk
(
"%02x "
, c);
178
}
179
}
180
printk
(
"\n"
);
181
}
182
183
void
nommu_dump_state
(
struct
pt_regs
*
regs
,
184
unsigned
long
ea
,
unsigned
long
vector
)
185
{
186
int
i
;
187
unsigned
long
addr
,
stack
= regs->
sp
;
188
189
printk
(
"\n\r[nommu_dump_state] :: ea %lx, vector %lx\n\r"
, ea, vector);
190
191
printk
(
"CPU #: %d\n"
192
" PC: %08lx SR: %08lx SP: %08lx\n"
,
193
0, regs->
pc
, regs->
sr
, regs->
sp
);
194
printk
(
"GPR00: %08lx GPR01: %08lx GPR02: %08lx GPR03: %08lx\n"
,
195
0
L
, regs->
gpr
[1], regs->
gpr
[2], regs->
gpr
[3]);
196
printk
(
"GPR04: %08lx GPR05: %08lx GPR06: %08lx GPR07: %08lx\n"
,
197
regs->
gpr
[4], regs->
gpr
[5], regs->
gpr
[6], regs->
gpr
[7]);
198
printk
(
"GPR08: %08lx GPR09: %08lx GPR10: %08lx GPR11: %08lx\n"
,
199
regs->
gpr
[8], regs->
gpr
[9], regs->
gpr
[10], regs->
gpr
[11]);
200
printk
(
"GPR12: %08lx GPR13: %08lx GPR14: %08lx GPR15: %08lx\n"
,
201
regs->
gpr
[12], regs->
gpr
[13], regs->
gpr
[14], regs->
gpr
[15]);
202
printk
(
"GPR16: %08lx GPR17: %08lx GPR18: %08lx GPR19: %08lx\n"
,
203
regs->
gpr
[16], regs->
gpr
[17], regs->
gpr
[18], regs->
gpr
[19]);
204
printk
(
"GPR20: %08lx GPR21: %08lx GPR22: %08lx GPR23: %08lx\n"
,
205
regs->
gpr
[20], regs->
gpr
[21], regs->
gpr
[22], regs->
gpr
[23]);
206
printk
(
"GPR24: %08lx GPR25: %08lx GPR26: %08lx GPR27: %08lx\n"
,
207
regs->
gpr
[24], regs->
gpr
[25], regs->
gpr
[26], regs->
gpr
[27]);
208
printk
(
"GPR28: %08lx GPR29: %08lx GPR30: %08lx GPR31: %08lx\n"
,
209
regs->
gpr
[28], regs->
gpr
[29], regs->
gpr
[30], regs->
gpr
[31]);
210
printk
(
" RES: %08lx oGPR11: %08lx\n"
,
211
regs->
gpr
[11], regs->
orig_gpr11
);
212
213
printk
(
"Process %s (pid: %d, stackpage=%08lx)\n"
,
214
((
struct
task_struct
*)(
__pa
(
current
)))->comm,
215
((
struct
task_struct
*)(
__pa
(
current
)))->
pid
,
216
(
unsigned
long
)
current
);
217
218
printk
(
"\nStack: "
);
219
printk
(
"Stack dump [0x%08lx]:\n"
, (
unsigned
long
)stack);
220
for
(i = 0; i <
kstack_depth_to_print
; i++) {
221
if
(((
long
)stack & (
THREAD_SIZE
- 1)) == 0)
222
break
;
223
stack++;
224
225
printk
(
"%lx :: sp + %02d: 0x%08lx\n"
, stack, i * 4,
226
*((
unsigned
long
*)(
__pa
(stack))));
227
}
228
printk
(
"\n"
);
229
230
printk
(
"Call Trace: "
);
231
i = 1;
232
while
(((
long
)stack & (
THREAD_SIZE
- 1)) != 0) {
233
addr = *((
unsigned
long
*)
__pa
(stack));
234
stack++;
235
236
if
(
kernel_text_address
(addr)) {
237
if
(i && ((i % 6) == 0))
238
printk
(
"\n "
);
239
printk
(
" [<%08lx>]"
, addr);
240
i++;
241
}
242
}
243
printk
(
"\n"
);
244
245
printk
(
"\nCode: "
);
246
247
for
(i = -24; i < 24; i++) {
248
unsigned
char
c
;
249
c = ((
unsigned
char
*)(
__pa
(regs->
pc
)))[
i
];
250
251
if
(i == 0)
252
printk
(
"(%02x) "
, c);
253
else
254
printk
(
"%02x "
, c);
255
}
256
printk
(
"\n"
);
257
}
258
259
/* This is normally the 'Oops' routine */
260
void
die
(
const
char
*
str
,
struct
pt_regs
*
regs
,
long
err
)
261
{
262
263
console_verbose();
264
printk
(
"\n%s#: %04lx\n"
, str, err & 0xffff);
265
show_registers
(regs);
266
#ifdef CONFIG_JUMP_UPON_UNHANDLED_EXCEPTION
267
printk
(
"\n\nUNHANDLED_EXCEPTION: entering infinite loop\n"
);
268
269
/* shut down interrupts */
270
local_irq_disable
();
271
272
__asm__
__volatile__(
"l.nop 1"
);
273
do
{}
while
(1);
274
#endif
275
do_exit
(
SIGSEGV
);
276
}
277
278
/* This is normally the 'Oops' routine */
279
void
die_if_kernel
(
const
char
*
str
,
struct
pt_regs
*
regs
,
long
err
)
280
{
281
if
(
user_mode
(regs))
282
return
;
283
284
die
(str, regs, err);
285
}
286
287
void
unhandled_exception
(
struct
pt_regs
*
regs
,
int
ea
,
int
vector
)
288
{
289
printk
(
"Unable to handle exception at EA =0x%x, vector 0x%x"
,
290
ea, vector);
291
die
(
"Oops"
, regs, 9);
292
}
293
294
void
__init
trap_init
(
void
)
295
{
296
/* Nothing needs to be done */
297
}
298
299
asmlinkage
void
do_trap
(
struct
pt_regs
*
regs
,
unsigned
long
address
)
300
{
301
siginfo_t
info
;
302
memset
(&info, 0,
sizeof
(info));
303
info.
si_signo
=
SIGTRAP
;
304
info.
si_code
=
TRAP_TRACE
;
305
info.si_addr = (
void
*)address;
306
force_sig_info
(
SIGTRAP
, &info,
current
);
307
308
regs->
pc
+= 4;
309
}
310
311
asmlinkage
void
do_unaligned_access
(
struct
pt_regs
*
regs
,
unsigned
long
address
)
312
{
313
siginfo_t
info
;
314
315
if
(
user_mode
(regs)) {
316
/* Send a SIGSEGV */
317
info.
si_signo
=
SIGSEGV
;
318
info.
si_errno
= 0;
319
/* info.si_code has been set above */
320
info.si_addr = (
void
*)address;
321
force_sig_info
(
SIGSEGV
, &info,
current
);
322
}
else
{
323
printk
(
"KERNEL: Unaligned Access 0x%.8lx\n"
, address);
324
show_registers
(regs);
325
die
(
"Die:"
, regs, address);
326
}
327
328
}
329
330
asmlinkage
void
do_bus_fault
(
struct
pt_regs
*
regs
,
unsigned
long
address
)
331
{
332
siginfo_t
info
;
333
334
if
(
user_mode
(regs)) {
335
/* Send a SIGBUS */
336
info.
si_signo
=
SIGBUS
;
337
info.
si_errno
= 0;
338
info.
si_code
=
BUS_ADRERR
;
339
info.si_addr = (
void
*)address;
340
force_sig_info
(
SIGBUS
, &info,
current
);
341
}
else
{
/* Kernel mode */
342
printk
(
"KERNEL: Bus error (SIGBUS) 0x%.8lx\n"
, address);
343
show_registers
(regs);
344
die
(
"Die:"
, regs, address);
345
}
346
}
347
348
asmlinkage
void
do_illegal_instruction
(
struct
pt_regs
*
regs
,
349
unsigned
long
address
)
350
{
351
siginfo_t
info
;
352
353
if
(
user_mode
(regs)) {
354
/* Send a SIGILL */
355
info.
si_signo
=
SIGILL
;
356
info.
si_errno
= 0;
357
info.
si_code
=
ILL_ILLOPC
;
358
info.si_addr = (
void
*)address;
359
force_sig_info
(
SIGBUS
, &info,
current
);
360
}
else
{
/* Kernel mode */
361
printk
(
"KERNEL: Illegal instruction (SIGILL) 0x%.8lx\n"
,
362
address);
363
show_registers
(regs);
364
die
(
"Die:"
, regs, address);
365
}
366
}
Generated on Thu Jan 10 2013 12:53:44 for Linux Kernel by
1.8.2