diff options
| author | Eric Paris <eparis@redhat.com> | 2013-11-22 18:57:08 -0500 |
|---|---|---|
| committer | Eric Paris <eparis@redhat.com> | 2013-11-22 18:57:54 -0500 |
| commit | fc582aef7dcc27a7120cf232c1e76c569c7b6eab (patch) | |
| tree | 7d275dd4ceab6067b91e9a25a5f6338b425fbccd /arch/um/kernel/trap.c | |
| parent | 9175c9d2aed528800175ef81c90569d00d23f9be (diff) | |
| parent | 5e01dc7b26d9f24f39abace5da98ccbd6a5ceb52 (diff) | |
Merge tag 'v3.12'
Linux 3.12
Conflicts:
fs/exec.c
Diffstat (limited to 'arch/um/kernel/trap.c')
| -rw-r--r-- | arch/um/kernel/trap.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index 089f3987e273..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, pmd_t *pmd; pte_t *pte; int err = -EFAULT; - unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | - (is_write ? FAULT_FLAG_WRITE : 0); + unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; *code_out = SEGV_MAPERR; @@ -42,6 +41,8 @@ int handle_page_fault(unsigned long address, unsigned long ip, if (in_atomic()) goto out_nosemaphore; + if (is_user) + flags |= FAULT_FLAG_USER; retry: down_read(&mm->mmap_sem); vma = find_vma(mm, address); @@ -58,12 +59,15 @@ retry: good_area: *code_out = SEGV_ACCERR; - if (is_write && !(vma->vm_flags & VM_WRITE)) - goto out; - - /* Don't require VM_READ|VM_EXEC for write faults! */ - if (!is_write && !(vma->vm_flags & (VM_READ | VM_EXEC))) - goto out; + if (is_write) { + if (!(vma->vm_flags & VM_WRITE)) + goto out; + flags |= FAULT_FLAG_WRITE; + } else { + /* Don't require VM_READ|VM_EXEC for write faults! */ + if (!(vma->vm_flags & (VM_READ | VM_EXEC))) + goto out; + } do { int fault; @@ -124,6 +128,8 @@ out_of_memory: * (which will retry the fault, or kill us if we got oom-killed). */ up_read(&mm->mmap_sem); + if (!is_user) + goto out_nosemaphore; pagefault_out_of_memory(); return 0; } |
