Commit b5c38535 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] exit_mmap() TASK_SIZE fix

exit_mmap() currently assumes that the exitting task used virtual address
span TASK_SIZE.

But on some platforms, TASK_SIZE is variable, based on current->mm.

But exit_mmap() can be called from (say) procfs's call to mmput.  In which
case current->mm has nothing to do with the mm which is being put in
mmput().

So rather than assuming that the mm which is being put is current->mm, we
need to calculate the virtual span of the mm.  Add a new per-arch macro
MM_VM_SIZE() for that.

Some platforms can currently go BUG over this (where?).  sparc64 is safe
because our TASK_SIZE is constant.

Platforms such as ia64 should stick the VM extent inside of mm_struct, I'd
suggest adding it to mm_context_t.

1) TASK_SIZE means what is valid for mmap()'s in the processes
   address space

2) MM_VM_SIZE means where things might be mapped for a MM, including
   private implementation-specific areas created by the kernel
   which the user cannot access
parent db378f4d
...@@ -23,8 +23,13 @@ extern int page_cluster; ...@@ -23,8 +23,13 @@ extern int page_cluster;
#include <asm/page.h> #include <asm/page.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/processor.h>
#include <asm/atomic.h> #include <asm/atomic.h>
#ifndef MM_VM_SIZE
#define MM_VM_SIZE(mm) TASK_SIZE
#endif
/* /*
* Linux kernel virtual memory manager primitives. * Linux kernel virtual memory manager primitives.
* The idea being to have a "virtual" mm in the same way * The idea being to have a "virtual" mm in the same way
......
...@@ -1442,7 +1442,7 @@ void exit_mmap(struct mm_struct *mm) ...@@ -1442,7 +1442,7 @@ void exit_mmap(struct mm_struct *mm)
vm_unacct_memory(nr_accounted); vm_unacct_memory(nr_accounted);
BUG_ON(mm->map_count); /* This is just debugging */ BUG_ON(mm->map_count); /* This is just debugging */
clear_page_tables(tlb, FIRST_USER_PGD_NR, USER_PTRS_PER_PGD); clear_page_tables(tlb, FIRST_USER_PGD_NR, USER_PTRS_PER_PGD);
tlb_finish_mmu(tlb, 0, TASK_SIZE); tlb_finish_mmu(tlb, 0, MM_VM_SIZE(mm));
vma = mm->mmap; vma = mm->mmap;
mm->mmap = mm->mmap_cache = NULL; mm->mmap = mm->mmap_cache = NULL;
......
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