aboutsummaryrefslogtreecommitdiff
path: root/arch/m32r/mm/fault.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/m32r/mm/fault.c')
-rw-r--r--arch/m32r/mm/fault.c35
1 files changed, 15 insertions, 20 deletions
diff --git a/arch/m32r/mm/fault.c b/arch/m32r/mm/fault.c
index 4a71df4c1b3..e9c6a8014bd 100644
--- a/arch/m32r/mm/fault.c
+++ b/arch/m32r/mm/fault.c
@@ -26,7 +26,6 @@
#include <linux/module.h>
#include <asm/m32r.h>
-#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/hardirq.h>
#include <asm/mmu_context.h>
@@ -79,7 +78,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code,
struct mm_struct *mm;
struct vm_area_struct * vma;
unsigned long page, addr;
- int write;
+ unsigned long flags = 0;
int fault;
siginfo_t info;
@@ -118,9 +117,12 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code,
if (in_atomic() || !mm)
goto bad_area_nosemaphore;
+ if (error_code & ACE_USERMODE)
+ flags |= FAULT_FLAG_USER;
+
/* When running in the kernel we expect faults to occur only to
* addresses in user space. All other faults represent errors in the
- * kernel and should generate an OOPS. Unfortunatly, in the case of an
+ * kernel and should generate an OOPS. Unfortunately, in the case of an
* erroneous fault occurring in a code path which already holds mmap_sem
* we will deadlock attempting to validate the fault against the
* address space. Luckily the kernel only validly references user
@@ -128,7 +130,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code,
* exceptions table.
*
* As the vast majority of faults will be valid we will only perform
- * the source reference check when there is a possibilty of a deadlock.
+ * the source reference check when there is a possibility of a deadlock.
* Attempt to lock the address space, if we cannot we then validate the
* source. If this is invalid we can skip the address space check,
* thus avoiding the deadlock.
@@ -167,14 +169,13 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code,
*/
good_area:
info.si_code = SEGV_ACCERR;
- write = 0;
switch (error_code & (ACE_WRITE|ACE_PROTECTION)) {
default: /* 3: write, present */
/* fall through */
case ACE_WRITE: /* write, not present */
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
- write++;
+ flags |= FAULT_FLAG_WRITE;
break;
case ACE_PROTECTION: /* read, present */
case 0: /* read, not present */
@@ -188,7 +189,6 @@ good_area:
if ((error_code & ACE_INSTRUCTION) && !(vma->vm_flags & VM_EXEC))
goto bad_area;
-survive:
/*
* If for any reason at all we couldn't handle the fault,
* make sure we exit gracefully rather than endlessly redo
@@ -196,7 +196,7 @@ survive:
*/
addr = (address & PAGE_MASK);
set_thread_fault_code(error_code);
- fault = handle_mm_fault(mm, vma, addr, write);
+ fault = handle_mm_fault(mm, vma, addr, flags);
if (unlikely(fault & VM_FAULT_ERROR)) {
if (fault & VM_FAULT_OOM)
goto out_of_memory;
@@ -271,15 +271,10 @@ no_context:
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (is_global_init(tsk)) {
- yield();
- down_read(&mm->mmap_sem);
- goto survive;
- }
- printk("VM: killing process %s\n", tsk->comm);
- if (error_code & ACE_USERMODE)
- do_group_exit(SIGKILL);
- goto no_context;
+ if (!(error_code & ACE_USERMODE))
+ goto no_context;
+ pagefault_out_of_memory();
+ return;
do_sigbus:
up_read(&mm->mmap_sem);
@@ -336,7 +331,7 @@ vmalloc_fault:
addr = (address & PAGE_MASK);
set_thread_fault_code(error_code);
- update_mmu_cache(NULL, addr, *pte_k);
+ update_mmu_cache(NULL, addr, pte_k);
set_thread_fault_code(0);
return;
}
@@ -349,7 +344,7 @@ vmalloc_fault:
#define ITLB_END (unsigned long *)(ITLB_BASE + (NR_TLB_ENTRIES * 8))
#define DTLB_END (unsigned long *)(DTLB_BASE + (NR_TLB_ENTRIES * 8))
void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr,
- pte_t pte)
+ pte_t *ptep)
{
volatile unsigned long *entry1, *entry2;
unsigned long pte_data, flags;
@@ -365,7 +360,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr,
vaddr = (vaddr & PAGE_MASK) | get_asid();
- pte_data = pte_val(pte);
+ pte_data = pte_val(*ptep);
#ifdef CONFIG_CHIP_OPSP
entry1 = (unsigned long *)ITLB_BASE;