]> git.hungrycats.org Git - linux/commitdiff
[PATCH] alpha: execve() fix
authorIvan Kokshaysky <ink@jurassic.park.msu.ru>
Tue, 15 Apr 2003 03:56:48 +0000 (20:56 -0700)
committerRichard Henderson <rth@are.twiddle.net>
Tue, 15 Apr 2003 03:56:48 +0000 (20:56 -0700)
The 2.5 kernels may hang on execve(). Most easily this can be reproduced
by submitting forms in mozilla, apparently because it does execve with
very long argument strings.
That's what happens in do_execve, I suppose:
bprm.mm = mm_alloc();
...
init_new_context(current, bprm.mm); here we update current ptbr
    with new mm->pgd
...
copy_strings;
interrupt -> do_softirq -> switch to ksoftirqd
...
switch back to do_execve;
copy_strings -  immediate page fault in copy_user that we can't
handle because the new ptbr has been activated
after context switch and current->mm is not
valid anymore.

The fix is to not update ptbr for current task in init_new_context(),
as we do it later in activate_mm() anyway.

With it my (UP) boxes look quite stable so far.

Ivan.

include/asm-alpha/mmu_context.h

index 5136e8a363295bbaef76e39e6a236349d99f4b73..a087254ea38a8a80c8014f9be681505bc2b6d5a9 100644 (file)
@@ -232,8 +232,9 @@ init_new_context(struct task_struct *tsk, struct mm_struct *mm)
        for (i = 0; i < NR_CPUS; i++)
                if (cpu_online(i))
                        mm->context[i] = 0;
-        tsk->thread_info->pcb.ptbr
-         = ((unsigned long)mm->pgd - IDENT_ADDR) >> PAGE_SHIFT;
+       if (tsk != current)
+               tsk->thread_info->pcb.ptbr
+                 = ((unsigned long)mm->pgd - IDENT_ADDR) >> PAGE_SHIFT;
        return 0;
 }