um: uml_dup_mmap() relies on ->mmap_sem being held, but activate_mm() doesn't hold it
authorAl Viro <viro@zeniv.linux.org.uk>
Thu, 23 Feb 2012 06:37:19 +0000 (01:37 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Wed, 21 Mar 2012 01:29:50 +0000 (21:29 -0400)
... while calling uml_dup_mmap()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
arch/um/include/asm/mmu_context.h
arch/um/kernel/skas/mmu.c

index 591b3d8d7614540680042ebcb8e90f190f195b13..aa4a743dc4ab1a6b5ef7afe373a73b87542bd640 100644 (file)
@@ -9,7 +9,7 @@
 #include <linux/sched.h>
 #include <asm/mmu.h>
 
-extern void arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm);
+extern void uml_setup_stubs(struct mm_struct *mm);
 extern void arch_exit_mmap(struct mm_struct *mm);
 
 #define deactivate_mm(tsk,mm)  do { } while (0)
@@ -23,7 +23,9 @@ static inline void activate_mm(struct mm_struct *old, struct mm_struct *new)
         * when the new ->mm is used for the first time.
         */
        __switch_mm(&new->context.id);
-       arch_dup_mmap(old, new);
+       down_write(&new->mmap_sem);
+       uml_setup_stubs(new);
+       up_write(&new->mmap_sem);
 }
 
 static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, 
@@ -39,6 +41,11 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
        }
 }
 
+static inline void arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm)
+{
+       uml_setup_stubs(mm);
+}
+
 static inline void enter_lazy_tlb(struct mm_struct *mm, 
                                  struct task_struct *tsk)
 {
index db2ef422c1b8d073041644e5576425e54ed68160..4947b319f53ad7d1359631bf3ae09e0e38731b12 100644 (file)
@@ -101,7 +101,7 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
        return ret;
 }
 
-void arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm)
+void uml_setup_stubs(struct mm_struct *mm)
 {
        struct page **pages;
        int err, ret;