| From d8aa712c30148ba26fd89a5dc14de95d4c375184 Mon Sep 17 00:00:00 2001 |
| From: Russell King <rmk+kernel@arm.linux.org.uk> |
| Date: Thu, 28 Nov 2013 21:43:40 +0000 |
| Subject: ARM: fix booting low-vectors machines |
| |
| From: Russell King <rmk+kernel@arm.linux.org.uk> |
| |
| commit d8aa712c30148ba26fd89a5dc14de95d4c375184 upstream. |
| |
| Commit f6f91b0d9fd9 (ARM: allow kuser helpers to be removed from the |
| vector page) required two pages for the vectors code. Although the |
| code setting up the initial page tables was updated, the code which |
| allocates page tables for new processes wasn't, neither was the code |
| which tears down the mappings. Fix this. |
| |
| Fixes: f6f91b0d9fd9 ("ARM: allow kuser helpers to be removed from the vector page") |
| Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/arm/include/asm/pgtable.h | 2 +- |
| arch/arm/mm/mmap.c | 2 +- |
| arch/arm/mm/pgd.c | 3 ++- |
| 3 files changed, 4 insertions(+), 3 deletions(-) |
| |
| --- a/arch/arm/include/asm/pgtable.h |
| +++ b/arch/arm/include/asm/pgtable.h |
| @@ -61,7 +61,7 @@ extern void __pgd_error(const char *file |
| * mapping to be mapped at. This is particularly important for |
| * non-high vector CPUs. |
| */ |
| -#define FIRST_USER_ADDRESS PAGE_SIZE |
| +#define FIRST_USER_ADDRESS (PAGE_SIZE * 2) |
| |
| /* |
| * Use TASK_SIZE as the ceiling argument for free_pgtables() and |
| --- a/arch/arm/mm/mmap.c |
| +++ b/arch/arm/mm/mmap.c |
| @@ -146,7 +146,7 @@ arch_get_unmapped_area_topdown(struct fi |
| |
| info.flags = VM_UNMAPPED_AREA_TOPDOWN; |
| info.length = len; |
| - info.low_limit = PAGE_SIZE; |
| + info.low_limit = FIRST_USER_ADDRESS; |
| info.high_limit = mm->mmap_base; |
| info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0; |
| info.align_offset = pgoff << PAGE_SHIFT; |
| --- a/arch/arm/mm/pgd.c |
| +++ b/arch/arm/mm/pgd.c |
| @@ -87,7 +87,8 @@ pgd_t *pgd_alloc(struct mm_struct *mm) |
| init_pud = pud_offset(init_pgd, 0); |
| init_pmd = pmd_offset(init_pud, 0); |
| init_pte = pte_offset_map(init_pmd, 0); |
| - set_pte_ext(new_pte, *init_pte, 0); |
| + set_pte_ext(new_pte + 0, init_pte[0], 0); |
| + set_pte_ext(new_pte + 1, init_pte[1], 0); |
| pte_unmap(init_pte); |
| pte_unmap(new_pte); |
| } |