diff options
Diffstat (limited to 'arch/arm/mm/idmap.c')
| -rw-r--r-- | arch/arm/mm/idmap.c | 20 | 
1 files changed, 16 insertions, 4 deletions
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c index 83cb3ac2709..c447ec70e86 100644 --- a/arch/arm/mm/idmap.c +++ b/arch/arm/mm/idmap.c @@ -9,7 +9,13 @@  #include <asm/sections.h>  #include <asm/system_info.h> +/* + * Note: accesses outside of the kernel image and the identity map area + * are not supported on any CPU using the idmap tables as its current + * page tables. + */  pgd_t *idmap_pgd; +phys_addr_t (*arch_virt_to_idmap) (unsigned long x);  #ifdef CONFIG_ARM_LPAE  static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end, @@ -24,6 +30,13 @@ static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end,  			pr_warning("Failed to allocate identity pmd.\n");  			return;  		} +		/* +		 * Copy the original PMD to ensure that the PMD entries for +		 * the kernel image are preserved. +		 */ +		if (!pud_none(*pud)) +			memcpy(pmd, pmd_offset(pud, 0), +			       PTRS_PER_PMD * sizeof(pmd_t));  		pud_populate(&init_mm, pud, pmd);  		pmd += pmd_index(addr);  	} else @@ -67,8 +80,9 @@ static void identity_mapping_add(pgd_t *pgd, const char *text_start,  	unsigned long addr, end;  	unsigned long next; -	addr = virt_to_phys(text_start); -	end = virt_to_phys(text_end); +	addr = virt_to_idmap(text_start); +	end = virt_to_idmap(text_end); +	pr_info("Setting up static identity map for 0x%lx - 0x%lx\n", addr, end);  	prot |= PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AF; @@ -90,8 +104,6 @@ static int __init init_static_idmap(void)  	if (!idmap_pgd)  		return -ENOMEM; -	pr_info("Setting up static identity map for 0x%p - 0x%p\n", -		__idmap_text_start, __idmap_text_end);  	identity_mapping_add(idmap_pgd, __idmap_text_start,  			     __idmap_text_end, 0);  | 
