diff options
Diffstat (limited to 'arch/um/kernel/trap.c')
-rw-r--r-- | arch/um/kernel/trap.c | 20 |
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; | ||
45 | retry: | 46 | retry: |
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 | ||
59 | good_area: | 60 | good_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; |