- 根目录:
- arch
- frv
- kernel
- traps.c
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/types.h>
#include <linux/user.h>
#include <linux/string.h>
#include <linux/linkage.h>
#include <linux/init.h>
#include <linux/module.h>
#include <asm/asm-offsets.h>
#include <asm/setup.h>
#include <asm/fpu.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/siginfo.h>
#include <asm/unaligned.h>
void show_backtrace(struct pt_regs *, unsigned long);
extern asmlinkage void __break_hijack_kernel_event(void);
asmlinkage void insn_access_error(unsigned long esfr1, unsigned long epcr0, unsigned long esr0)
{
siginfo_t info;
die_if_kernel("-- Insn Access Error --\n"
"EPCR0 : %08lx\n"
"ESR0 : %08lx\n",
epcr0, esr0);
info.si_signo = SIGSEGV;
info.si_code = SEGV_ACCERR;
info.si_errno = 0;
info.si_addr = (void __user *) ((epcr0 & EPCR0_V) ? (epcr0 & EPCR0_PC) : __frame->pc);
force_sig_info(info.si_signo, &info, current);
}
asmlinkage void illegal_instruction(unsigned long esfr1, unsigned long epcr0, unsigned long esr0)
{
siginfo_t info;
die_if_kernel("-- Illegal Instruction --\n"
"EPCR0 : %08lx\n"
"ESR0 : %08lx\n"
"ESFR1 : %08lx\n",
epcr0, esr0, esfr1);
info.si_errno = 0;
info.si_addr = (void __user *) ((epcr0 & EPCR0_V) ? (epcr0 & EPCR0_PC) : __frame->pc);
switch (__frame->tbr & TBR_TT) {
case TBR_TT_ILLEGAL_INSTR:
info.si_signo = SIGILL;
info.si_code = ILL_ILLOPC;
break;
case TBR_TT_PRIV_INSTR:
info.si_signo = SIGILL;
info.si_code = ILL_PRVOPC;
break;
case TBR_TT_TRAP2 ... TBR_TT_TRAP126:
info.si_signo = SIGILL;
info.si_code = ILL_ILLTRP;
break;
case TBR_TT_TRAP1:
case TBR_TT_BREAK:
info.si_signo = SIGTRAP;
info.si_code =
(__frame->__status & REG__STATUS_STEPPED) ? TRAP_TRACE : TRAP_BRKPT;
break;
}
force_sig_info(info.si_signo, &info, current);
}
asmlinkage void atomic_operation(unsigned long esfr1, unsigned long epcr0,
unsigned long esr0)
{
static DEFINE_SPINLOCK(atomic_op_lock);
unsigned long x, y, z;
unsigned long __user *p;
mm_segment_t oldfs;
siginfo_t info;
int ret;
y = 0;
z = 0;
oldfs = get_fs();
if (!user_mode(__frame))
set_fs(KERNEL_DS);
switch (__frame->tbr & TBR_TT) {
case TBR_TT_ATOMIC_CMPXCHG32:
p = (unsigned long __user *) __frame->gr8;
x = __frame->gr9;
y = __frame->gr10;
for (;;) {
ret = get_user(z, p);
if (ret < 0)
goto error;
if (z != x)
goto done;
spin_lock_irq(&atomic_op_lock);
if (__get_user(z, p) == 0) {
if (z != x)
goto done2;
if (__put_user(y, p) == 0)
goto done2;
goto error2;
}
spin_unlock_irq(&atomic_op_lock);
}
case TBR_TT_ATOMIC_XCHG32:
p = (unsigned long __user *) __frame->gr8;
y = __frame->gr9;
for (;;) {
ret = get_user(z, p);
if (ret < 0)
goto error;
spin_lock_irq(&atomic_op_lock);
if (__get_user(z, p) == 0) {
if (__put_user(y, p) == 0)
goto done2;
goto error2;
}
spin_unlock_irq(&atomic_op_lock);
}
case TBR_TT_ATOMIC_XOR:
p = (unsigned long __user *) __frame->gr8;
x = __frame->gr9;
for (;;) {
ret = get_user(z, p);
if (ret < 0)
goto error;
spin_lock_irq(&atomic_op_lock);
if (__get_user(z, p) == 0) {
y = x ^ z;
if (__put_user(y, p) == 0)
goto done2;
goto error2;
}
spin_unlock_irq(&atomic_op_lock);
}
case TBR_TT_ATOMIC_OR:
p = (unsigned long __user *) __frame->gr8;
x = __frame->gr9;
for (;;) {
ret = get_user(z, p);
if (ret < 0)
goto error;
spin_lock_irq(&atomic_op_lock);
if (__get_user(z, p) == 0) {
y = x ^ z;
if (__put_user(y, p) == 0)
goto done2;
goto error2;
}
spin_unlock_irq(&atomic_op_lock);
}
case TBR_TT_ATOMIC_AND:
p = (unsigned long __user *) __frame->gr8;
x = __frame->gr9;
for (;;) {
ret = get_user(z, p);
if (ret < 0)
goto error;
spin_lock_irq(&atomic_op_lock);
if (__get_user(z, p) == 0) {
y = x & z;
if (__put_user(y, p) == 0)
goto done2;
goto error2;
}
spin_unlock_irq(&atomic_op_lock);
}
case TBR_TT_ATOMIC_SUB:
p = (unsigned long __user *) __frame->gr8;
x = __frame->gr9;
for (;;) {
ret = get_user(z, p);
if (ret < 0)
goto error;
spin_lock_irq(&atomic_op_lock);
if (__get_user(z, p) == 0) {
y = z - x;
if (__put_user(y, p) == 0)
goto done2;
goto error2;
}
spin_unlock_irq(&atomic_op_lock);
}
case TBR_TT_ATOMIC_ADD:
p = (unsigned long __user *) __frame->gr8;
x = __frame->gr9;
for (;;) {
ret = get_user(z, p);
if (ret < 0)
goto error;
spin_lock_irq(&atomic_op_lock);
if (__get_user(z, p) == 0) {
y = z + x;
if (__put_user(y, p) == 0)
goto done2;
goto error2;
}
spin_unlock_irq(&atomic_op_lock);
}
default:
BUG();
}
done2:
spin_unlock_irq(&atomic_op_lock);
done:
if (!user_mode(__frame))
set_fs(oldfs);
__frame->gr5 = z;
__frame->gr9 = y;
return;
error2:
spin_unlock_irq(&atomic_op_lock);
error:
if (!user_mode(__frame))
set_fs(oldfs);
__frame->pc -= 4;
die_if_kernel("-- Atomic Op Error --\n");
info.si_signo = SIGSEGV;
info.si_code = SEGV_ACCERR;
info.si_errno = 0;
info.si_addr = (void __user *) __frame->pc;
force_sig_info(info.si_signo, &info, current);
}
asmlinkage void media_exception(unsigned long msr0, unsigned long msr1)
{
siginfo_t info;
die_if_kernel("-- Media Exception --\n"
"MSR0 : %08lx\n"
"MSR1 : %08lx\n",
msr0, msr1);
info.si_signo = SIGFPE;
info.si_code = FPE_MDAOVF;
info.si_errno = 0;
info.si_addr = (void __user *) __frame->pc;
force_sig_info(info.si_signo, &info, current);
}
asmlinkage void memory_access_exception(unsigned long esr0,
unsigned long ear0,
unsigned long epcr0)
{
siginfo_t info;
#ifdef CONFIG_MMU
unsigned long fixup;
fixup = search_exception_table(__frame->pc);
if (fixup) {
__frame->pc = fixup;
return;
}
#endif
die_if_kernel("-- Memory Access Exception --\n"
"ESR0 : %08lx\n"
"EAR0 : %08lx\n"
"EPCR0 : %08lx\n",
esr0, ear0, epcr0);
info.si_signo = SIGSEGV;
info.si_code = SEGV_ACCERR;
info.si_errno = 0;
info.si_addr = NULL;
if ((esr0 & (ESRx_VALID | ESR0_EAV)) == (ESRx_VALID | ESR0_EAV))
info.si_addr = (void __user *) ear0;
force_sig_info(info.si_signo, &info, current);
}
asmlinkage void data_access_error(unsigned long esfr1, unsigned long esr15, unsigned long ear15)
{
siginfo_t info;
die_if_kernel("-- Data Access Error --\n"
"ESR15 : %08lx\n"
"EAR15 : %08lx\n",
esr15, ear15);
info.si_signo = SIGSEGV;
info.si_code = SEGV_ACCERR;
info.si_errno = 0;
info.si_addr = (void __user *)
(((esr15 & (ESRx_VALID|ESR15_EAV)) == (ESRx_VALID|ESR15_EAV)) ? ear15 : 0);
force_sig_info(info.si_signo, &info, current);
}
asmlinkage void data_store_error(unsigned long esfr1, unsigned long esr15)
{
die_if_kernel("-- Data Store Error --\n"
"ESR15 : %08lx\n",
esr15);
BUG();
}
asmlinkage void division_exception(unsigned long esfr1, unsigned long esr0, unsigned long isr)
{
siginfo_t info;
die_if_kernel("-- Division Exception --\n"
"ESR0 : %08lx\n"
"ISR : %08lx\n",
esr0, isr);
info.si_signo = SIGFPE;
info.si_code = FPE_INTDIV;
info.si_errno = 0;
info.si_addr = (void __user *) __frame->pc;
force_sig_info(info.si_signo, &info, current);
}
asmlinkage void compound_exception(unsigned long esfr1,
unsigned long esr0, unsigned long esr14, unsigned long esr15,
unsigned long msr0, unsigned long msr1)
{
die_if_kernel("-- Compound Exception --\n"
"ESR0 : %08lx\n"
"ESR15 : %08lx\n"
"ESR15 : %08lx\n"
"MSR0 : %08lx\n"
"MSR1 : %08lx\n",
esr0, esr14, esr15, msr0, msr1);
BUG();
}
void dump_stack(void)
{
show_stack(NULL, NULL);
}
EXPORT_SYMBOL(dump_stack);
void show_stack(struct task_struct *task, unsigned long *sp)
{
}
void show_trace_task(struct task_struct *tsk)
{
printk("CONTEXT: stack=0x%lx frame=0x%p LR=0x%lx RET=0x%lx\n",
tsk->thread.sp, tsk->thread.frame, tsk->thread.lr, tsk->thread.sched_lr);
}
static const char *regnames[] = {
"PSR ", "ISR ", "CCR ", "CCCR",
"LR ", "LCR ", "PC ", "_stt",
"sys ", "GR8*", "GNE0", "GNE1",
"IACH", "IACL",
"TBR ", "SP ", "FP ", "GR3 ",
"GR4 ", "GR5 ", "GR6 ", "GR7 ",
"GR8 ", "GR9 ", "GR10", "GR11",
"GR12", "GR13", "GR14", "GR15",
"GR16", "GR17", "GR18", "GR19",
"GR20", "GR21", "GR22", "GR23",
"GR24", "GR25", "GR26", "GR27",
"EFRM", "CURR", "GR30", "BFRM"
};
void show_regs(struct pt_regs *regs)
{
unsigned long *reg;
int loop;
printk("\n");
printk("Frame: @%08lx [%s]\n",
(unsigned long) regs,
regs->psr & PSR_S ? "kernel" : "user");
reg = (unsigned long *) regs;
for (loop = 0; loop < NR_PT_REGS; loop++) {
printk("%s %08lx", regnames[loop + 0], reg[loop + 0]);
if (loop == NR_PT_REGS - 1 || loop % 5 == 4)
printk("\n");
else
printk(" | ");
}
printk("Process %s (pid: %d)\n", current->comm, current->pid);
}
void die_if_kernel(const char *str, ...)
{
char buffer[256];
va_list va;
if (user_mode(__frame))
return;
va_start(va, str);
vsprintf(buffer, str, va);
va_end(va);
console_verbose();
printk("\n===================================\n");
printk("%s\n", buffer);
show_backtrace(__frame, 0);
__break_hijack_kernel_event();
do_exit(SIGSEGV);
}
static void show_backtrace_regs(struct pt_regs *frame)
{
unsigned long *reg;
int loop;
printk("<-- %s Frame: @%p -->\n",
frame->psr & PSR_S ? "Kernel Mode" : "User Mode",
frame);
reg = (unsigned long *) frame;
for (loop = 0; loop < NR_PT_REGS; loop++) {
printk("%s %08lx", regnames[loop + 0], reg[loop + 0]);
if (loop == NR_PT_REGS - 1 || loop % 5 == 4)
printk("\n");
else
printk(" | ");
}
printk("--------\n");
}
void show_backtrace(struct pt_regs *frame, unsigned long sp)
{
struct pt_regs *frame0;
unsigned long tos = 0, stop = 0, base;
int format;
base = ((((unsigned long) frame) + 8191) & ~8191) - sizeof(struct user_context);
frame0 = (struct pt_regs *) base;
if (sp) {
tos = sp;
stop = (unsigned long) frame;
}
printk("\nProcess %s (pid: %d)\n\n", current->comm, current->pid);
for (;;) {
format = 0;
while (tos < stop) {
if (format == 0)
printk(" %04lx :", tos & 0xffff);
printk(" %08lx", *(unsigned long *) tos);
tos += 4;
format++;
if (format == 8) {
printk("\n");
format = 0;
}
}
if (format > 0)
printk("\n");
if (frame == frame0)
break;
tos = frame->sp;
if (((unsigned long) frame) + sizeof(*frame) != tos) {
printk("-- TOS %08lx does not follow frame %p --\n",
tos, frame);
break;
}
show_backtrace_regs(frame);
stop = (unsigned long) frame->next_frame;
if (stop != base &&
(stop < tos ||
stop > base ||
(stop < base && stop + sizeof(*frame) > base) ||
stop & 3)) {
printk("-- next_frame %08lx is invalid (range %08lx-%08lx) --\n",
stop, tos, base);
break;
}
frame = frame->next_frame;
}
show_backtrace_regs(frame0);
}
void __init trap_init (void)
{
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 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
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659