diff options
Diffstat (limited to 'arch/arm/mm')
-rw-r--r-- | arch/arm/mm/blockops.c | 3 | ||||
-rw-r--r-- | arch/arm/mm/fault.c | 75 | ||||
-rw-r--r-- | arch/arm/mm/proc-arm1020.S | 4 | ||||
-rw-r--r-- | arch/arm/mm/proc-arm1020e.S | 4 |
4 files changed, 46 insertions, 40 deletions
diff --git a/arch/arm/mm/blockops.c b/arch/arm/mm/blockops.c index 806c6eeb1b0c..4f5ee2d08996 100644 --- a/arch/arm/mm/blockops.c +++ b/arch/arm/mm/blockops.c | |||
@@ -25,13 +25,14 @@ blk_flush_kern_dcache_page(void *kaddr) | |||
25 | { | 25 | { |
26 | asm( | 26 | asm( |
27 | "add r1, r0, %0 \n\ | 27 | "add r1, r0, %0 \n\ |
28 | sub r1, r1, %1 \n\ | ||
28 | 1: .word 0xec401f0e @ mcrr p15, 0, r0, r1, c14, 0 @ blocking \n\ | 29 | 1: .word 0xec401f0e @ mcrr p15, 0, r0, r1, c14, 0 @ blocking \n\ |
29 | mov r0, #0 \n\ | 30 | mov r0, #0 \n\ |
30 | mcr p15, 0, r0, c7, c5, 0 \n\ | 31 | mcr p15, 0, r0, c7, c5, 0 \n\ |
31 | mcr p15, 0, r0, c7, c10, 4 \n\ | 32 | mcr p15, 0, r0, c7, c10, 4 \n\ |
32 | mov pc, lr" | 33 | mov pc, lr" |
33 | : | 34 | : |
34 | : "I" (PAGE_SIZE)); | 35 | : "I" (PAGE_SIZE), "I" (L1_CACHE_BYTES)); |
35 | } | 36 | } |
36 | 37 | ||
37 | /* | 38 | /* |
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index e25b4fd8412c..65bfe84b6d67 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c | |||
@@ -372,49 +372,50 @@ do_bad(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
372 | static struct fsr_info { | 372 | static struct fsr_info { |
373 | int (*fn)(unsigned long addr, unsigned int fsr, struct pt_regs *regs); | 373 | int (*fn)(unsigned long addr, unsigned int fsr, struct pt_regs *regs); |
374 | int sig; | 374 | int sig; |
375 | int code; | ||
375 | const char *name; | 376 | const char *name; |
376 | } fsr_info[] = { | 377 | } fsr_info[] = { |
377 | /* | 378 | /* |
378 | * The following are the standard ARMv3 and ARMv4 aborts. ARMv5 | 379 | * The following are the standard ARMv3 and ARMv4 aborts. ARMv5 |
379 | * defines these to be "precise" aborts. | 380 | * defines these to be "precise" aborts. |
380 | */ | 381 | */ |
381 | { do_bad, SIGSEGV, "vector exception" }, | 382 | { do_bad, SIGSEGV, 0, "vector exception" }, |
382 | { do_bad, SIGILL, "alignment exception" }, | 383 | { do_bad, SIGILL, BUS_ADRALN, "alignment exception" }, |
383 | { do_bad, SIGKILL, "terminal exception" }, | 384 | { do_bad, SIGKILL, 0, "terminal exception" }, |
384 | { do_bad, SIGILL, "alignment exception" }, | 385 | { do_bad, SIGILL, BUS_ADRALN, "alignment exception" }, |
385 | { do_bad, SIGBUS, "external abort on linefetch" }, | 386 | { do_bad, SIGBUS, 0, "external abort on linefetch" }, |
386 | { do_translation_fault, SIGSEGV, "section translation fault" }, | 387 | { do_translation_fault, SIGSEGV, SEGV_MAPERR, "section translation fault" }, |
387 | { do_bad, SIGBUS, "external abort on linefetch" }, | 388 | { do_bad, SIGBUS, 0, "external abort on linefetch" }, |
388 | { do_page_fault, SIGSEGV, "page translation fault" }, | 389 | { do_page_fault, SIGSEGV, SEGV_MAPERR, "page translation fault" }, |
389 | { do_bad, SIGBUS, "external abort on non-linefetch" }, | 390 | { do_bad, SIGBUS, 0, "external abort on non-linefetch" }, |
390 | { do_bad, SIGSEGV, "section domain fault" }, | 391 | { do_bad, SIGSEGV, SEGV_ACCERR, "section domain fault" }, |
391 | { do_bad, SIGBUS, "external abort on non-linefetch" }, | 392 | { do_bad, SIGBUS, 0, "external abort on non-linefetch" }, |
392 | { do_bad, SIGSEGV, "page domain fault" }, | 393 | { do_bad, SIGSEGV, SEGV_ACCERR, "page domain fault" }, |
393 | { do_bad, SIGBUS, "external abort on translation" }, | 394 | { do_bad, SIGBUS, 0, "external abort on translation" }, |
394 | { do_sect_fault, SIGSEGV, "section permission fault" }, | 395 | { do_sect_fault, SIGSEGV, SEGV_ACCERR, "section permission fault" }, |
395 | { do_bad, SIGBUS, "external abort on translation" }, | 396 | { do_bad, SIGBUS, 0, "external abort on translation" }, |
396 | { do_page_fault, SIGSEGV, "page permission fault" }, | 397 | { do_page_fault, SIGSEGV, SEGV_ACCERR, "page permission fault" }, |
397 | /* | 398 | /* |
398 | * The following are "imprecise" aborts, which are signalled by bit | 399 | * The following are "imprecise" aborts, which are signalled by bit |
399 | * 10 of the FSR, and may not be recoverable. These are only | 400 | * 10 of the FSR, and may not be recoverable. These are only |
400 | * supported if the CPU abort handler supports bit 10. | 401 | * supported if the CPU abort handler supports bit 10. |
401 | */ | 402 | */ |
402 | { do_bad, SIGBUS, "unknown 16" }, | 403 | { do_bad, SIGBUS, 0, "unknown 16" }, |
403 | { do_bad, SIGBUS, "unknown 17" }, | 404 | { do_bad, SIGBUS, 0, "unknown 17" }, |
404 | { do_bad, SIGBUS, "unknown 18" }, | 405 | { do_bad, SIGBUS, 0, "unknown 18" }, |
405 | { do_bad, SIGBUS, "unknown 19" }, | 406 | { do_bad, SIGBUS, 0, "unknown 19" }, |
406 | { do_bad, SIGBUS, "lock abort" }, /* xscale */ | 407 | { do_bad, SIGBUS, 0, "lock abort" }, /* xscale */ |
407 | { do_bad, SIGBUS, "unknown 21" }, | 408 | { do_bad, SIGBUS, 0, "unknown 21" }, |
408 | { do_bad, SIGBUS, "imprecise external abort" }, /* xscale */ | 409 | { do_bad, SIGBUS, BUS_OBJERR, "imprecise external abort" }, /* xscale */ |
409 | { do_bad, SIGBUS, "unknown 23" }, | 410 | { do_bad, SIGBUS, 0, "unknown 23" }, |
410 | { do_bad, SIGBUS, "dcache parity error" }, /* xscale */ | 411 | { do_bad, SIGBUS, 0, "dcache parity error" }, /* xscale */ |
411 | { do_bad, SIGBUS, "unknown 25" }, | 412 | { do_bad, SIGBUS, 0, "unknown 25" }, |
412 | { do_bad, SIGBUS, "unknown 26" }, | 413 | { do_bad, SIGBUS, 0, "unknown 26" }, |
413 | { do_bad, SIGBUS, "unknown 27" }, | 414 | { do_bad, SIGBUS, 0, "unknown 27" }, |
414 | { do_bad, SIGBUS, "unknown 28" }, | 415 | { do_bad, SIGBUS, 0, "unknown 28" }, |
415 | { do_bad, SIGBUS, "unknown 29" }, | 416 | { do_bad, SIGBUS, 0, "unknown 29" }, |
416 | { do_bad, SIGBUS, "unknown 30" }, | 417 | { do_bad, SIGBUS, 0, "unknown 30" }, |
417 | { do_bad, SIGBUS, "unknown 31" } | 418 | { do_bad, SIGBUS, 0, "unknown 31" } |
418 | }; | 419 | }; |
419 | 420 | ||
420 | void __init | 421 | void __init |
@@ -435,15 +436,19 @@ asmlinkage void | |||
435 | do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | 436 | do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) |
436 | { | 437 | { |
437 | const struct fsr_info *inf = fsr_info + (fsr & 15) + ((fsr & (1 << 10)) >> 6); | 438 | const struct fsr_info *inf = fsr_info + (fsr & 15) + ((fsr & (1 << 10)) >> 6); |
439 | struct siginfo info; | ||
438 | 440 | ||
439 | if (!inf->fn(addr, fsr, regs)) | 441 | if (!inf->fn(addr, fsr, regs)) |
440 | return; | 442 | return; |
441 | 443 | ||
442 | printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n", | 444 | printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n", |
443 | inf->name, fsr, addr); | 445 | inf->name, fsr, addr); |
444 | force_sig(inf->sig, current); | 446 | |
445 | show_pte(current->mm, addr); | 447 | info.si_signo = inf->sig; |
446 | die_if_kernel("Oops", regs, 0); | 448 | info.si_errno = 0; |
449 | info.si_code = inf->code; | ||
450 | info.si_addr = (void __user *)addr; | ||
451 | notify_die("", regs, &info, fsr, 0); | ||
447 | } | 452 | } |
448 | 453 | ||
449 | asmlinkage void | 454 | asmlinkage void |
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S index 1f325231b9e4..5c0ae5260d1c 100644 --- a/arch/arm/mm/proc-arm1020.S +++ b/arch/arm/mm/proc-arm1020.S | |||
@@ -445,14 +445,14 @@ __arm1020_setup: | |||
445 | /* | 445 | /* |
446 | * R | 446 | * R |
447 | * .RVI ZFRS BLDP WCAM | 447 | * .RVI ZFRS BLDP WCAM |
448 | * .0.1 1001 ..11 0101 /* FIXME: why no V bit? */ | 448 | * .011 1001 ..11 0101 |
449 | */ | 449 | */ |
450 | .type arm1020_cr1_clear, #object | 450 | .type arm1020_cr1_clear, #object |
451 | .type arm1020_cr1_set, #object | 451 | .type arm1020_cr1_set, #object |
452 | arm1020_cr1_clear: | 452 | arm1020_cr1_clear: |
453 | .word 0x593f | 453 | .word 0x593f |
454 | arm1020_cr1_set: | 454 | arm1020_cr1_set: |
455 | .word 0x1935 | 455 | .word 0x3935 |
456 | 456 | ||
457 | __INITDATA | 457 | __INITDATA |
458 | 458 | ||
diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S index 142a2c2d6f0b..d69389c4d4ba 100644 --- a/arch/arm/mm/proc-arm1020e.S +++ b/arch/arm/mm/proc-arm1020e.S | |||
@@ -427,14 +427,14 @@ __arm1020e_setup: | |||
427 | /* | 427 | /* |
428 | * R | 428 | * R |
429 | * .RVI ZFRS BLDP WCAM | 429 | * .RVI ZFRS BLDP WCAM |
430 | * .0.1 1001 ..11 0101 /* FIXME: why no V bit? */ | 430 | * .011 1001 ..11 0101 |
431 | */ | 431 | */ |
432 | .type arm1020e_cr1_clear, #object | 432 | .type arm1020e_cr1_clear, #object |
433 | .type arm1020e_cr1_set, #object | 433 | .type arm1020e_cr1_set, #object |
434 | arm1020e_cr1_clear: | 434 | arm1020e_cr1_clear: |
435 | .word 0x5f3f | 435 | .word 0x5f3f |
436 | arm1020e_cr1_set: | 436 | arm1020e_cr1_set: |
437 | .word 0x1935 | 437 | .word 0x3935 |
438 | 438 | ||
439 | __INITDATA | 439 | __INITDATA |
440 | 440 | ||