summaryrefslogtreecommitdiff
path: root/fs/exec.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@athlon.transmeta.com>2002-02-04 18:03:57 -0800
committerLinus Torvalds <torvalds@athlon.transmeta.com>2002-02-04 18:03:57 -0800
commitcc80f8f99c1ba16d54b0af64cb3911cd0146259e (patch)
treebc033080018817d4095c2891c76e9c19c68c83bd /fs/exec.c
parent8565fe850b04acbfdc4c24cdcafeed359bb0f2b3 (diff)
v2.4.2.4 -> v2.4.2.5
- Rik van Riel and others: mm rw-semaphore (ps/top ok when swapping) - IDE: 256 sectors at a time is legal, but apparently confuses some drives. Max out at 255 sectors instead. - Petko Manolov: USB pegasus driver update - make the boottime memory map printout at least almost readable. - USB driver updates - pte_alloc()/pmd_alloc() need page_table_lock.
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c41
1 files changed, 21 insertions, 20 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 835d771363a8..08ea898ab285 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -262,27 +262,28 @@ void put_dirty_page(struct task_struct * tsk, struct page *page, unsigned long a
if (page_count(page) != 1)
printk("mem_map disagrees with %p at %08lx\n", page, address);
pgd = pgd_offset(tsk->mm, address);
- pmd = pmd_alloc(pgd, address);
- if (!pmd) {
- __free_page(page);
- force_sig(SIGKILL, tsk);
- return;
- }
- pte = pte_alloc(pmd, address);
- if (!pte) {
- __free_page(page);
- force_sig(SIGKILL, tsk);
- return;
- }
- if (!pte_none(*pte)) {
- pte_ERROR(*pte);
- __free_page(page);
- return;
- }
+
+ spin_lock(&tsk->mm->page_table_lock);
+ pmd = pmd_alloc(tsk->mm, pgd, address);
+ if (!pmd)
+ goto out;
+ pte = pte_alloc(tsk->mm, pmd, address);
+ if (!pte)
+ goto out;
+ if (!pte_none(*pte))
+ goto out;
flush_dcache_page(page);
flush_page_to_ram(page);
set_pte(pte, pte_mkdirty(pte_mkwrite(mk_pte(page, PAGE_COPY))));
-/* no need for flush_tlb */
+ spin_unlock(&tsk->mm->page_table_lock);
+
+ /* no need for flush_tlb */
+ return;
+out:
+ spin_unlock(&tsk->mm->page_table_lock);
+ __free_page(page);
+ force_sig(SIGKILL, tsk);
+ return;
}
int setup_arg_pages(struct linux_binprm *bprm)
@@ -302,7 +303,7 @@ int setup_arg_pages(struct linux_binprm *bprm)
if (!mpnt)
return -ENOMEM;
- down(&current->mm->mmap_sem);
+ down_write(&current->mm->mmap_sem);
{
mpnt->vm_mm = current->mm;
mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
@@ -326,7 +327,7 @@ int setup_arg_pages(struct linux_binprm *bprm)
}
stack_base += PAGE_SIZE;
}
- up(&current->mm->mmap_sem);
+ up_write(&current->mm->mmap_sem);
return 0;
}