summary refs log tree commit diff
path: root/arch/um/kernel
diff options
context:
space:
mode:
authorRichard Weinberger <richard@nod.at>2014-07-20 13:16:20 +0200
committerRichard Weinberger <richard@nod.at>2014-07-20 13:16:20 +0200
commit468f65976a8d065ee1f27782337f4ee85a9151c5 (patch)
treebf7325540763882142df28d23b4974e8e280d04b /arch/um/kernel
parent284e6d39516cc7f9fbceebb259849fcb41559a7b (diff)
downloadlinux-468f65976a8d065ee1f27782337f4ee85a9151c5.tar.gz
um: Fix hung task in fix_range_common()
If do_ops() fails we have to release current->mm->mmap_sem
otherwise the failing task will never terminate.

Reported-by: Toralf Förster <toralf.foerster@gmx.de>
Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'arch/um/kernel')
-rw-r--r--arch/um/kernel/tlb.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c
index 1fc619e5dfe9..f1b3eb14b855 100644
--- a/arch/um/kernel/tlb.c
+++ b/arch/um/kernel/tlb.c
@@ -12,6 +12,7 @@
 #include <mem_user.h>
 #include <os.h>
 #include <skas.h>
+#include <kern_util.h>
 
 struct host_vm_change {
 	struct host_vm_op {
@@ -286,8 +287,11 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
 	/* This is not an else because ret is modified above */
 	if (ret) {
 		printk(KERN_ERR "fix_range_common: failed, killing current "
-		       "process\n");
+		       "process: %d\n", task_tgid_vnr(current));
+		/* We are under mmap_sem, release it such that current can terminate */
+		up_write(&current->mm->mmap_sem);
 		force_sig(SIGKILL, current);
+		do_signal();
 	}
 }