aboutsummaryrefslogtreecommitdiffstats
path: root/arch/tile/mm/fault.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/tile/mm/fault.c')
-rw-r--r--arch/tile/mm/fault.c64
1 files changed, 13 insertions, 51 deletions
diff --git a/arch/tile/mm/fault.c b/arch/tile/mm/fault.c
index 9b6b92f07de..0011f06b4fe 100644
--- a/arch/tile/mm/fault.c
+++ b/arch/tile/mm/fault.c
@@ -39,32 +39,11 @@
39#include <asm/system.h> 39#include <asm/system.h>
40#include <asm/pgalloc.h> 40#include <asm/pgalloc.h>
41#include <asm/sections.h> 41#include <asm/sections.h>
42#include <asm/traps.h>
43#include <asm/syscalls.h>
42 44
43#include <arch/interrupts.h> 45#include <arch/interrupts.h>
44 46
45/*
46 * Unlock any spinlocks which will prevent us from getting the
47 * message out
48 */
49void bust_spinlocks(int yes)
50{
51 int loglevel_save = console_loglevel;
52
53 if (yes) {
54 oops_in_progress = 1;
55 return;
56 }
57 oops_in_progress = 0;
58 /*
59 * OK, the message is on the console. Now we call printk()
60 * without oops_in_progress set so that printk will give klogd
61 * a poke. Hold onto your hats...
62 */
63 console_loglevel = 15; /* NMI oopser may have shut the console up */
64 printk(" ");
65 console_loglevel = loglevel_save;
66}
67
68static noinline void force_sig_info_fault(int si_signo, int si_code, 47static noinline void force_sig_info_fault(int si_signo, int si_code,
69 unsigned long address, int fault_num, struct task_struct *tsk) 48 unsigned long address, int fault_num, struct task_struct *tsk)
70{ 49{
@@ -301,10 +280,10 @@ static int handle_page_fault(struct pt_regs *regs,
301 */ 280 */
302 stack_offset = stack_pointer & (THREAD_SIZE-1); 281 stack_offset = stack_pointer & (THREAD_SIZE-1);
303 if (stack_offset < THREAD_SIZE / 8) { 282 if (stack_offset < THREAD_SIZE / 8) {
304 printk(KERN_ALERT "Potential stack overrun: sp %#lx\n", 283 pr_alert("Potential stack overrun: sp %#lx\n",
305 stack_pointer); 284 stack_pointer);
306 show_regs(regs); 285 show_regs(regs);
307 printk(KERN_ALERT "Killing current process %d/%s\n", 286 pr_alert("Killing current process %d/%s\n",
308 tsk->pid, tsk->comm); 287 tsk->pid, tsk->comm);
309 do_group_exit(SIGKILL); 288 do_group_exit(SIGKILL);
310 } 289 }
@@ -422,7 +401,7 @@ good_area:
422 } else if (write) { 401 } else if (write) {
423#ifdef TEST_VERIFY_AREA 402#ifdef TEST_VERIFY_AREA
424 if (!is_page_fault && regs->cs == KERNEL_CS) 403 if (!is_page_fault && regs->cs == KERNEL_CS)
425 printk("WP fault at "REGFMT"\n", regs->eip); 404 pr_err("WP fault at "REGFMT"\n", regs->eip);
426#endif 405#endif
427 if (!(vma->vm_flags & VM_WRITE)) 406 if (!(vma->vm_flags & VM_WRITE))
428 goto bad_area; 407 goto bad_area;
@@ -450,6 +429,7 @@ good_area:
450 else 429 else
451 tsk->min_flt++; 430 tsk->min_flt++;
452 431
432#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC()
453 /* 433 /*
454 * If this was an asynchronous fault, 434 * If this was an asynchronous fault,
455 * restart the appropriate engine. 435 * restart the appropriate engine.
@@ -472,6 +452,7 @@ good_area:
472 break; 452 break;
473#endif 453#endif
474 } 454 }
455#endif
475 456
476 up_read(&mm->mmap_sem); 457 up_read(&mm->mmap_sem);
477 return 1; 458 return 1;
@@ -514,17 +495,17 @@ no_context:
514 pte_t *pte = lookup_address(address); 495 pte_t *pte = lookup_address(address);
515 496
516 if (pte && pte_present(*pte) && !pte_exec_kernel(*pte)) 497 if (pte && pte_present(*pte) && !pte_exec_kernel(*pte))
517 printk(KERN_CRIT "kernel tried to execute" 498 pr_crit("kernel tried to execute"
518 " non-executable page - exploit attempt?" 499 " non-executable page - exploit attempt?"
519 " (uid: %d)\n", current->uid); 500 " (uid: %d)\n", current->uid);
520 } 501 }
521#endif 502#endif
522 if (address < PAGE_SIZE) 503 if (address < PAGE_SIZE)
523 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference\n"); 504 pr_alert("Unable to handle kernel NULL pointer dereference\n");
524 else 505 else
525 printk(KERN_ALERT "Unable to handle kernel paging request\n"); 506 pr_alert("Unable to handle kernel paging request\n");
526 printk(" at virtual address "REGFMT", pc "REGFMT"\n", 507 pr_alert(" at virtual address "REGFMT", pc "REGFMT"\n",
527 address, regs->pc); 508 address, regs->pc);
528 509
529 show_regs(regs); 510 show_regs(regs);
530 511
@@ -555,7 +536,7 @@ out_of_memory:
555 down_read(&mm->mmap_sem); 536 down_read(&mm->mmap_sem);
556 goto survive; 537 goto survive;
557 } 538 }
558 printk("VM: killing process %s\n", tsk->comm); 539 pr_alert("VM: killing process %s\n", tsk->comm);
559 if (!is_kernel_mode) 540 if (!is_kernel_mode)
560 do_group_exit(SIGKILL); 541 do_group_exit(SIGKILL);
561 goto no_context; 542 goto no_context;
@@ -573,31 +554,12 @@ do_sigbus:
573 554
574#ifndef __tilegx__ 555#ifndef __tilegx__
575 556
576extern char sys_cmpxchg[], __sys_cmpxchg_end[];
577extern char __sys_cmpxchg_grab_lock[];
578extern char __start_atomic_asm_code[], __end_atomic_asm_code[];
579
580/*
581 * We return this structure in registers to avoid having to write
582 * additional save/restore code in the intvec.S caller.
583 */
584struct intvec_state {
585 void *handler;
586 unsigned long vecnum;
587 unsigned long fault_num;
588 unsigned long info;
589 unsigned long retval;
590};
591
592/* We must release ICS before panicking or we won't get anywhere. */ 557/* We must release ICS before panicking or we won't get anywhere. */
593#define ics_panic(fmt, ...) do { \ 558#define ics_panic(fmt, ...) do { \
594 __insn_mtspr(SPR_INTERRUPT_CRITICAL_SECTION, 0); \ 559 __insn_mtspr(SPR_INTERRUPT_CRITICAL_SECTION, 0); \
595 panic(fmt, __VA_ARGS__); \ 560 panic(fmt, __VA_ARGS__); \
596} while (0) 561} while (0)
597 562
598void do_page_fault(struct pt_regs *regs, int fault_num,
599 unsigned long address, unsigned long write);
600
601/* 563/*
602 * When we take an ITLB or DTLB fault or access violation in the 564 * When we take an ITLB or DTLB fault or access violation in the
603 * supervisor while the critical section bit is set, the hypervisor is 565 * supervisor while the critical section bit is set, the hypervisor is