From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Message-Id: <20130518021648.841787160@goodmis.org> Date: Fri, 17 May 2013 22:16:41 -0400 From: Steven Rostedt To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Hugh Dickins , Catalin Marinas , Russell King , Andrew Morton Subject: [ 044/136 ] mm: allow arch code to control the user page table ceiling References: <20130518021557.139113314@goodmis.org> Content-Disposition: inline; filename=0044-mm-allow-arch-code-to-control-the-user-page-table-ce.patch Sender: linux-kernel-owner@vger.kernel.org List-ID: 3.6.11.4 stable review patch. If anyone has any objections, please let me know. ------------------ From: Hugh Dickins [ Upstream commit 6ee8630e02be6dd89926ca0fbc21af68b23dc087 ] On architectures where a pgd entry may be shared between user and kernel (e.g. ARM+LPAE), freeing page tables needs a ceiling other than 0. This patch introduces a generic USER_PGTABLES_CEILING that arch code can override. It is the responsibility of the arch code setting the ceiling to ensure the complete freeing of the page tables (usually in pgd_free()). [catalin.marinas@arm.com: commit log; shift_arg_pages(), asm-generic/pgtables.h changes] Signed-off-by: Hugh Dickins Signed-off-by: Catalin Marinas Cc: Russell King Cc: [3.3+] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Steven Rostedt --- fs/exec.c | 4 ++-- include/asm-generic/pgtable.h | 10 ++++++++++ mm/mmap.c | 4 ++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/fs/exec.c b/fs/exec.c index fab2c6d..5b0d397 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -623,7 +623,7 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) * when the old and new regions overlap clear from new_end. */ free_pgd_range(&tlb, new_end, old_end, new_end, - vma->vm_next ? vma->vm_next->vm_start : 0); + vma->vm_next ? vma->vm_next->vm_start : USER_PGTABLES_CEILING); } else { /* * otherwise, clean from old_start; this is done to not touch @@ -632,7 +632,7 @@ static int shift_arg_pages(struct vm_area_struct *vma, unsigned long shift) * for the others its just a little faster. */ free_pgd_range(&tlb, old_start, old_end, new_end, - vma->vm_next ? vma->vm_next->vm_start : 0); + vma->vm_next ? vma->vm_next->vm_start : USER_PGTABLES_CEILING); } tlb_finish_mmu(&tlb, new_end, old_end); diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index ff4947b..0084135 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h @@ -7,6 +7,16 @@ #include #include +/* + * On almost all architectures and configurations, 0 can be used as the + * upper ceiling to free_pgtables(): on many architectures it has the same + * effect as using TASK_SIZE. However, there is one configuration which + * must impose a more careful limit, to avoid freeing kernel pgtables. + */ +#ifndef USER_PGTABLES_CEILING +#define USER_PGTABLES_CEILING 0UL +#endif + #ifndef __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS extern int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address, pte_t *ptep, diff --git a/mm/mmap.c b/mm/mmap.c index cf6434e..3ddb799 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1912,7 +1912,7 @@ static void unmap_region(struct mm_struct *mm, update_hiwater_rss(mm); unmap_vmas(&tlb, vma, start, end); free_pgtables(&tlb, vma, prev ? prev->vm_end : FIRST_USER_ADDRESS, - next ? next->vm_start : 0); + next ? next->vm_start : USER_PGTABLES_CEILING); tlb_finish_mmu(&tlb, start, end); } @@ -2294,7 +2294,7 @@ void exit_mmap(struct mm_struct *mm) /* Use -1 here to ensure all VMAs in the mm are unmapped */ unmap_vmas(&tlb, vma, 0, -1); - free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, 0); + free_pgtables(&tlb, vma, FIRST_USER_ADDRESS, USER_PGTABLES_CEILING); tlb_finish_mmu(&tlb, 0, -1); /* -- 1.7.10.4