aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/kernel/trap.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/kernel/trap.c')
-rw-r--r--arch/um/kernel/trap.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index b2f5adf838dd..5c3aef74237f 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -30,8 +30,7 @@ int handle_page_fault(unsigned long address, unsigned long ip,
30 pmd_t *pmd; 30 pmd_t *pmd;
31 pte_t *pte; 31 pte_t *pte;
32 int err = -EFAULT; 32 int err = -EFAULT;
33 unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | 33 unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
34 (is_write ? FAULT_FLAG_WRITE : 0);
35 34
36 *code_out = SEGV_MAPERR; 35 *code_out = SEGV_MAPERR;
37 36
@@ -42,6 +41,8 @@ int handle_page_fault(unsigned long address, unsigned long ip,
42 if (in_atomic()) 41 if (in_atomic())
43 goto out_nosemaphore; 42 goto out_nosemaphore;
44 43
44 if (is_user)
45 flags |= FAULT_FLAG_USER;
45retry: 46retry:
46 down_read(&mm->mmap_sem); 47 down_read(&mm->mmap_sem);
47 vma = find_vma(mm, address); 48 vma = find_vma(mm, address);
@@ -58,12 +59,15 @@ retry:
58 59
59good_area: 60good_area:
60 *code_out = SEGV_ACCERR; 61 *code_out = SEGV_ACCERR;
61 if (is_write && !(vma->vm_flags & VM_WRITE)) 62 if (is_write) {
62 goto out; 63 if (!(vma->vm_flags & VM_WRITE))
63 64 goto out;
64 /* Don't require VM_READ|VM_EXEC for write faults! */ 65 flags |= FAULT_FLAG_WRITE;
65 if (!is_write && !(vma->vm_flags & (VM_READ | VM_EXEC))) 66 } else {
66 goto out; 67 /* Don't require VM_READ|VM_EXEC for write faults! */
68 if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
69 goto out;
70 }
67 71
68 do { 72 do {
69 int fault; 73 int fault;