diff options
Diffstat (limited to 'arch/um/kernel/trap.c')
-rw-r--r-- | arch/um/kernel/trap.c | 24 |
1 files changed, 8 insertions, 16 deletions
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index 44e490419495..7384d8accfe7 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c | |||
@@ -64,11 +64,10 @@ good_area: | |||
64 | 64 | ||
65 | do { | 65 | do { |
66 | int fault; | 66 | int fault; |
67 | survive: | 67 | |
68 | fault = handle_mm_fault(mm, vma, address, is_write); | 68 | fault = handle_mm_fault(mm, vma, address, is_write); |
69 | if (unlikely(fault & VM_FAULT_ERROR)) { | 69 | if (unlikely(fault & VM_FAULT_ERROR)) { |
70 | if (fault & VM_FAULT_OOM) { | 70 | if (fault & VM_FAULT_OOM) { |
71 | err = -ENOMEM; | ||
72 | goto out_of_memory; | 71 | goto out_of_memory; |
73 | } else if (fault & VM_FAULT_SIGBUS) { | 72 | } else if (fault & VM_FAULT_SIGBUS) { |
74 | err = -EACCES; | 73 | err = -EACCES; |
@@ -104,18 +103,14 @@ out: | |||
104 | out_nosemaphore: | 103 | out_nosemaphore: |
105 | return err; | 104 | return err; |
106 | 105 | ||
107 | /* | ||
108 | * We ran out of memory, or some other thing happened to us that made | ||
109 | * us unable to handle the page fault gracefully. | ||
110 | */ | ||
111 | out_of_memory: | 106 | out_of_memory: |
112 | if (is_global_init(current)) { | 107 | /* |
113 | up_read(&mm->mmap_sem); | 108 | * We ran out of memory, call the OOM killer, and return the userspace |
114 | yield(); | 109 | * (which will retry the fault, or kill us if we got oom-killed). |
115 | down_read(&mm->mmap_sem); | 110 | */ |
116 | goto survive; | 111 | up_read(&mm->mmap_sem); |
117 | } | 112 | pagefault_out_of_memory(); |
118 | goto out; | 113 | return 0; |
119 | } | 114 | } |
120 | 115 | ||
121 | static void bad_segv(struct faultinfo fi, unsigned long ip) | 116 | static void bad_segv(struct faultinfo fi, unsigned long ip) |
@@ -214,9 +209,6 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, | |||
214 | si.si_addr = (void __user *)address; | 209 | si.si_addr = (void __user *)address; |
215 | current->thread.arch.faultinfo = fi; | 210 | current->thread.arch.faultinfo = fi; |
216 | force_sig_info(SIGBUS, &si, current); | 211 | force_sig_info(SIGBUS, &si, current); |
217 | } else if (err == -ENOMEM) { | ||
218 | printk(KERN_INFO "VM: killing process %s\n", current->comm); | ||
219 | do_exit(SIGKILL); | ||
220 | } else { | 212 | } else { |
221 | BUG_ON(err != -EFAULT); | 213 | BUG_ON(err != -EFAULT); |
222 | si.si_signo = SIGSEGV; | 214 | si.si_signo = SIGSEGV; |