Commit 114c71ee authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] rmap 33 install_arg_page vma

From: Hugh Dickins <hugh@veritas.com>

anon_vma will need to pass vma to put_dirty_page, so change it and its
various callers (setup_arg_pages and its 32-on-64-bit arch variants); and
please, let's rename it to install_arg_page.

Earlier attempt to do this (rmap 26 __setup_arg_pages) tried to clean up
those callers instead, but failed to boot: so now apply rmap 27's memset
initialization of vmas to these callers too; which relieves them from
needing the recently included linux/mempolicy.h.

While there, moved install_arg_page's flush_dcache_page up before
page_table_lock - doesn't in fact matter at all, just saves one worry when
researching flush_dcache_page locking constraints.
parent 5911438d
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/security.h> #include <linux/security.h>
#include <linux/mempolicy.h>
#include <asm/param.h> #include <asm/param.h>
#include <asm/signal.h> #include <asm/signal.h>
...@@ -169,6 +168,8 @@ ia32_setup_arg_pages (struct linux_binprm *bprm, int executable_stack) ...@@ -169,6 +168,8 @@ ia32_setup_arg_pages (struct linux_binprm *bprm, int executable_stack)
return -ENOMEM; return -ENOMEM;
} }
memset(mpnt, 0, sizeof(*mpnt));
down_write(&current->mm->mmap_sem); down_write(&current->mm->mmap_sem);
{ {
mpnt->vm_mm = current->mm; mpnt->vm_mm = current->mm;
...@@ -182,11 +183,6 @@ ia32_setup_arg_pages (struct linux_binprm *bprm, int executable_stack) ...@@ -182,11 +183,6 @@ ia32_setup_arg_pages (struct linux_binprm *bprm, int executable_stack)
mpnt->vm_flags = VM_STACK_FLAGS; mpnt->vm_flags = VM_STACK_FLAGS;
mpnt->vm_page_prot = (mpnt->vm_flags & VM_EXEC)? mpnt->vm_page_prot = (mpnt->vm_flags & VM_EXEC)?
PAGE_COPY_EXEC: PAGE_COPY; PAGE_COPY_EXEC: PAGE_COPY;
mpnt->vm_ops = NULL;
mpnt->vm_pgoff = 0;
mpnt->vm_file = NULL;
mpnt->vm_private_data = 0;
mpol_set_vma_default(mpnt);
insert_vm_struct(current->mm, mpnt); insert_vm_struct(current->mm, mpnt);
current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
} }
...@@ -195,7 +191,7 @@ ia32_setup_arg_pages (struct linux_binprm *bprm, int executable_stack) ...@@ -195,7 +191,7 @@ ia32_setup_arg_pages (struct linux_binprm *bprm, int executable_stack)
struct page *page = bprm->page[i]; struct page *page = bprm->page[i];
if (page) { if (page) {
bprm->page[i] = NULL; bprm->page[i] = NULL;
put_dirty_page(current, page, stack_base, mpnt->vm_page_prot); install_arg_page(mpnt, page, stack_base);
} }
stack_base += PAGE_SIZE; stack_base += PAGE_SIZE;
} }
......
...@@ -38,7 +38,6 @@ ...@@ -38,7 +38,6 @@
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/version.h> #include <linux/version.h>
#include <linux/mempolicy.h>
#include <asm/bitops.h> #include <asm/bitops.h>
#include <asm/errno.h> #include <asm/errno.h>
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/swap.h> #include <linux/swap.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/mempolicy.h>
#include <asm/a.out.h> #include <asm/a.out.h>
#include <asm/bitops.h> #include <asm/bitops.h>
...@@ -218,7 +217,7 @@ free_initrd_mem (unsigned long start, unsigned long end) ...@@ -218,7 +217,7 @@ free_initrd_mem (unsigned long start, unsigned long end)
} }
/* /*
* This is like put_dirty_page() but installs a clean page in the kernel's page table. * This installs a clean page in the kernel's page table.
*/ */
struct page * struct page *
put_kernel_page (struct page *page, unsigned long address, pgprot_t pgprot) put_kernel_page (struct page *page, unsigned long address, pgprot_t pgprot)
......
...@@ -58,6 +58,8 @@ int setup_arg_pages32(struct linux_binprm *bprm, int executable_stack) ...@@ -58,6 +58,8 @@ int setup_arg_pages32(struct linux_binprm *bprm, int executable_stack)
return -ENOMEM; return -ENOMEM;
} }
memset(mpnt, 0, sizeof(*mpnt));
down_write(&mm->mmap_sem); down_write(&mm->mmap_sem);
{ {
mpnt->vm_mm = mm; mpnt->vm_mm = mm;
...@@ -66,11 +68,6 @@ int setup_arg_pages32(struct linux_binprm *bprm, int executable_stack) ...@@ -66,11 +68,6 @@ int setup_arg_pages32(struct linux_binprm *bprm, int executable_stack)
/* executable stack setting would be applied here */ /* executable stack setting would be applied here */
mpnt->vm_page_prot = PAGE_COPY; mpnt->vm_page_prot = PAGE_COPY;
mpnt->vm_flags = VM_STACK_FLAGS; mpnt->vm_flags = VM_STACK_FLAGS;
mpnt->vm_ops = NULL;
mpnt->vm_pgoff = 0;
mpnt->vm_file = NULL;
mpol_set_vma_default(mpnt);
mpnt->vm_private_data = (void *) 0;
insert_vm_struct(mm, mpnt); insert_vm_struct(mm, mpnt);
mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
} }
...@@ -79,7 +76,7 @@ int setup_arg_pages32(struct linux_binprm *bprm, int executable_stack) ...@@ -79,7 +76,7 @@ int setup_arg_pages32(struct linux_binprm *bprm, int executable_stack)
struct page *page = bprm->page[i]; struct page *page = bprm->page[i];
if (page) { if (page) {
bprm->page[i] = NULL; bprm->page[i] = NULL;
put_dirty_page(current,page,stack_base,PAGE_COPY); install_arg_page(mpnt, page, stack_base);
} }
stack_base += PAGE_SIZE; stack_base += PAGE_SIZE;
} }
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#include <linux/binfmts.h> #include <linux/binfmts.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/security.h> #include <linux/security.h>
#include <linux/mempolicy.h>
#include <asm/segment.h> #include <asm/segment.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
...@@ -350,6 +349,8 @@ int setup_arg_pages(struct linux_binprm *bprm, int executable_stack) ...@@ -350,6 +349,8 @@ int setup_arg_pages(struct linux_binprm *bprm, int executable_stack)
return -ENOMEM; return -ENOMEM;
} }
memset(mpnt, 0, sizeof(*mpnt));
down_write(&mm->mmap_sem); down_write(&mm->mmap_sem);
{ {
mpnt->vm_mm = mm; mpnt->vm_mm = mm;
...@@ -363,11 +364,6 @@ int setup_arg_pages(struct linux_binprm *bprm, int executable_stack) ...@@ -363,11 +364,6 @@ int setup_arg_pages(struct linux_binprm *bprm, int executable_stack)
mpnt->vm_flags = vm_stack_flags32; mpnt->vm_flags = vm_stack_flags32;
mpnt->vm_page_prot = (mpnt->vm_flags & VM_EXEC) ? mpnt->vm_page_prot = (mpnt->vm_flags & VM_EXEC) ?
PAGE_COPY_EXEC : PAGE_COPY; PAGE_COPY_EXEC : PAGE_COPY;
mpnt->vm_ops = NULL;
mpnt->vm_pgoff = 0;
mpnt->vm_file = NULL;
mpol_set_vma_default(mpnt);
mpnt->vm_private_data = (void *) 0;
insert_vm_struct(mm, mpnt); insert_vm_struct(mm, mpnt);
mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
} }
...@@ -376,7 +372,7 @@ int setup_arg_pages(struct linux_binprm *bprm, int executable_stack) ...@@ -376,7 +372,7 @@ int setup_arg_pages(struct linux_binprm *bprm, int executable_stack)
struct page *page = bprm->page[i]; struct page *page = bprm->page[i];
if (page) { if (page) {
bprm->page[i] = NULL; bprm->page[i] = NULL;
put_dirty_page(current,page,stack_base,mpnt->vm_page_prot); install_arg_page(mpnt, page, stack_base);
} }
stack_base += PAGE_SIZE; stack_base += PAGE_SIZE;
} }
......
...@@ -46,7 +46,6 @@ ...@@ -46,7 +46,6 @@
#include <linux/security.h> #include <linux/security.h>
#include <linux/syscalls.h> #include <linux/syscalls.h>
#include <linux/rmap.h> #include <linux/rmap.h>
#include <linux/mempolicy.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
...@@ -294,17 +293,19 @@ EXPORT_SYMBOL(copy_strings_kernel); ...@@ -294,17 +293,19 @@ EXPORT_SYMBOL(copy_strings_kernel);
* This routine is used to map in a page into an address space: needed by * This routine is used to map in a page into an address space: needed by
* execve() for the initial stack and environment pages. * execve() for the initial stack and environment pages.
* *
* tsk->mm->mmap_sem is held for writing. * vma->vm_mm->mmap_sem is held for writing.
*/ */
void put_dirty_page(struct task_struct *tsk, struct page *page, void install_arg_page(struct vm_area_struct *vma,
unsigned long address, pgprot_t prot) struct page *page, unsigned long address)
{ {
struct mm_struct *mm = tsk->mm; struct mm_struct *mm = vma->vm_mm;
pgd_t * pgd; pgd_t * pgd;
pmd_t * pmd; pmd_t * pmd;
pte_t * pte; pte_t * pte;
flush_dcache_page(page);
pgd = pgd_offset(mm, address); pgd = pgd_offset(mm, address);
spin_lock(&mm->page_table_lock); spin_lock(&mm->page_table_lock);
pmd = pmd_alloc(mm, pgd, address); pmd = pmd_alloc(mm, pgd, address);
if (!pmd) if (!pmd)
...@@ -318,8 +319,8 @@ void put_dirty_page(struct task_struct *tsk, struct page *page, ...@@ -318,8 +319,8 @@ void put_dirty_page(struct task_struct *tsk, struct page *page,
} }
mm->rss++; mm->rss++;
lru_cache_add_active(page); lru_cache_add_active(page);
flush_dcache_page(page); set_pte(pte, pte_mkdirty(pte_mkwrite(mk_pte(
set_pte(pte, pte_mkdirty(pte_mkwrite(mk_pte(page, prot)))); page, vma->vm_page_prot))));
page_add_anon_rmap(page, mm, address); page_add_anon_rmap(page, mm, address);
pte_unmap(pte); pte_unmap(pte);
spin_unlock(&mm->page_table_lock); spin_unlock(&mm->page_table_lock);
...@@ -329,7 +330,7 @@ void put_dirty_page(struct task_struct *tsk, struct page *page, ...@@ -329,7 +330,7 @@ void put_dirty_page(struct task_struct *tsk, struct page *page,
out: out:
spin_unlock(&mm->page_table_lock); spin_unlock(&mm->page_table_lock);
__free_page(page); __free_page(page);
force_sig(SIGKILL, tsk); force_sig(SIGKILL, current);
} }
int setup_arg_pages(struct linux_binprm *bprm, int executable_stack) int setup_arg_pages(struct linux_binprm *bprm, int executable_stack)
...@@ -435,8 +436,7 @@ int setup_arg_pages(struct linux_binprm *bprm, int executable_stack) ...@@ -435,8 +436,7 @@ int setup_arg_pages(struct linux_binprm *bprm, int executable_stack)
struct page *page = bprm->page[i]; struct page *page = bprm->page[i];
if (page) { if (page) {
bprm->page[i] = NULL; bprm->page[i] = NULL;
put_dirty_page(current, page, stack_base, install_arg_page(mpnt, page, stack_base);
mpnt->vm_page_prot);
} }
stack_base += PAGE_SIZE; stack_base += PAGE_SIZE;
} }
......
...@@ -530,8 +530,7 @@ extern int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma, un ...@@ -530,8 +530,7 @@ extern int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma, un
extern int handle_mm_fault(struct mm_struct *mm,struct vm_area_struct *vma, unsigned long address, int write_access); extern int handle_mm_fault(struct mm_struct *mm,struct vm_area_struct *vma, unsigned long address, int write_access);
extern int make_pages_present(unsigned long addr, unsigned long end); extern int make_pages_present(unsigned long addr, unsigned long end);
extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write); extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
void put_dirty_page(struct task_struct *tsk, struct page *page, void install_arg_page(struct vm_area_struct *, struct page *, unsigned long);
unsigned long address, pgprot_t prot);
int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start, int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start,
int len, int write, int force, struct page **pages, struct vm_area_struct **vmas); int len, int write, int force, struct page **pages, struct vm_area_struct **vmas);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment