[linux-yocto] [PATCH 10/15] arm: mmu: Fix truncated 40-bit physaddr (LPAE)

Bruce Ashfield bruce.ashfield at windriver.com
Thu Jan 30 11:58:40 PST 2014


On 14-01-20 12:56 PM, Charlie Paul wrote:
> From: Anders Berg <anders.berg at lsi.com>
>
> Wrong type for parameter 'phys' caused adress to be truncated to 32-bits,
> causing iotable_init() to produce wrong MMU mappings on LPAE system.
>
> Signed-off-by: Anders Berg <anders.berg at lsi.com>
> ---
>   arch/arm/mm/mmu.c |  108 +++++++++++++++++++++++++----------------------------
>   1 file changed, 51 insertions(+), 57 deletions(-)
>
> diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
> index daf336f..0da2304 100644
> --- a/arch/arm/mm/mmu.c
> +++ b/arch/arm/mm/mmu.c
> @@ -55,15 +55,17 @@ pmd_t *top_pmd;
>   #define CPOLICY_WRITEALLOC	4
>
>   static unsigned int cachepolicy __initdata = CPOLICY_WRITEBACK;
> -static unsigned int ecc_mask __initdata = 0;
> +static unsigned int ecc_mask __initdata;
>   pgprot_t pgprot_user;
> +EXPORT_SYMBOL(pgprot_user);
> +
>   pgprot_t pgprot_kernel;
> +EXPORT_SYMBOL(pgprot_kernel);
> +
>   pgprot_t pgprot_hyp_device;
>   pgprot_t pgprot_s2;
>   pgprot_t pgprot_s2_device;
>
> -EXPORT_SYMBOL(pgprot_user);
> -EXPORT_SYMBOL(pgprot_kernel);
>
>   struct cachepolicy {
>   	const char	policy[16];
> @@ -135,7 +137,7 @@ static int __init early_cachepolicy(char *p)
>   		}
>   	}
>   	if (i == ARRAY_SIZE(cache_policies))
> -		printk(KERN_ERR "ERROR: unknown or unsupported cache policy\n");
> +		pr_err("ERROR: unknown or unsupported cache policy\n");

We have mixes of cleanups, and functional changes.

>   	/*
>   	 * This restriction is partly to do with the way we boot; it is
>   	 * unpredictable to have memory mapped using two different sets of
> @@ -144,7 +146,7 @@ static int __init early_cachepolicy(char *p)
>   	 * page tables.
>   	 */
>   	if (cpu_architecture() >= CPU_ARCH_ARMv6) {
> -		printk(KERN_WARNING "Only cachepolicy=writeback supported on ARMv6 and later\n");
> +		pr_warn("Only cachepolicy=writeback supported on ARMv6 and later\n");
>   		cachepolicy = CPOLICY_WRITEBACK;
>   	}
>   	flush_cache_all();
> @@ -156,7 +158,7 @@ early_param("cachepolicy", early_cachepolicy);
>   static int __init early_nocache(char *__unused)
>   {
>   	char *p = "buffered";
> -	printk(KERN_WARNING "nocache is deprecated; use cachepolicy=%s\n", p);
> +	pr_warn("nocache is deprecated; use cachepolicy=%s\n", p);
>   	early_cachepolicy(p);
>   	return 0;
>   }
> @@ -165,7 +167,7 @@ early_param("nocache", early_nocache);
>   static int __init early_nowrite(char *__unused)
>   {
>   	char *p = "uncached";
> -	printk(KERN_WARNING "nowb is deprecated; use cachepolicy=%s\n", p);
> +	pr_warn("nowb is deprecated; use cachepolicy=%s\n", p);
>   	early_cachepolicy(p);
>   	return 0;
>   }
> @@ -216,20 +218,20 @@ void adjust_cr(unsigned long mask, unsigned long set)
>
>   static int __init early_cachepolicy(char *p)
>   {
> -	pr_warning("cachepolicy kernel parameter not supported without cp15\n");
> +	pr_warn("cachepolicy kernel parameter not supported without cp15\n");
>   }
>   early_param("cachepolicy", early_cachepolicy);
>
>   static int __init noalign_setup(char *__unused)
>   {
> -	pr_warning("noalign kernel parameter not supported without cp15\n");
> +	pr_warn("noalign kernel parameter not supported without cp15\n");
>   }
>   __setup("noalign", noalign_setup);
>
>   #endif /* ifdef CONFIG_CPU_CP15 / else */
>
> -#define PROT_PTE_DEVICE		L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_XN
> -#define PROT_SECT_DEVICE	PMD_TYPE_SECT|PMD_SECT_AP_WRITE
> +#define PROT_PTE_DEVICE		(L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_XN)
> +#define PROT_SECT_DEVICE	(PMD_TYPE_SECT|PMD_SECT_AP_WRITE)
>
>   static struct mem_type mem_types[] = {
>   	[MT_DEVICE] = {		  /* Strongly ordered / ARMv6 shared device */
> @@ -556,7 +558,7 @@ static void __init build_mem_type_table(void)
>   		mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WB;
>   		break;
>   	}
> -	printk("Memory policy: ECC %sabled, Data cache %s\n",
> +	pr_info("Memory policy: ECC %sabled, Data cache %s\n",
>   		ecc_mask ? "en" : "dis", cp->policy);
>
>   	for (i = 0; i < ARRAY_SIZE(mem_types); i++) {
> @@ -595,7 +597,8 @@ static void __init *early_alloc(unsigned long sz)
>   	return early_alloc_aligned(sz, sz);
>   }
>
> -static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned long prot)
> +static pte_t * __init early_pte_alloc(pmd_t *pmd,
> +		unsigned long addr, unsigned long prot)
>   {
>   	if (pmd_none(*pmd)) {
>   		pte_t *pte = early_alloc(PTE_HWTABLE_OFF + PTE_HWTABLE_SIZE);
> @@ -675,7 +678,7 @@ static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
>   }
>
>   static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
> -	unsigned long end, unsigned long phys, const struct mem_type *type)
> +	unsigned long end, phys_addr_t phys, const struct mem_type *type)
>   {
>   	pud_t *pud = pud_offset(pgd, addr);
>   	unsigned long next;
> @@ -700,9 +703,8 @@ static void __init create_36bit_mapping(struct map_desc *md,
>   	length = PAGE_ALIGN(md->length);
>
>   	if (!(cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3())) {
> -		printk(KERN_ERR "MM: CPU does not support supersection "
> -		       "mapping for 0x%08llx at 0x%08lx\n",
> -		       (long long)__pfn_to_phys((u64)md->pfn), addr);
> +		pr_err("MM: CPU does not support supersection mapping for 0x%08llx at 0x%08lx\n",
> +			(long long)__pfn_to_phys((u64)md->pfn), addr);
>   		return;
>   	}
>
> @@ -713,16 +715,14 @@ static void __init create_36bit_mapping(struct map_desc *md,
>   	 *	of the actual domain assignments in use.
>   	 */
>   	if (type->domain) {
> -		printk(KERN_ERR "MM: invalid domain in supersection "
> -		       "mapping for 0x%08llx at 0x%08lx\n",
> -		       (long long)__pfn_to_phys((u64)md->pfn), addr);
> +		pr_err("MM: invalid domain in supersection mapping for 0x%08llx at 0x%08lx\n",
> +				(long long)__pfn_to_phys((u64)md->pfn), addr);
>   		return;
>   	}
>
>   	if ((addr | length | __pfn_to_phys(md->pfn)) & ~SUPERSECTION_MASK) {
> -		printk(KERN_ERR "MM: cannot create mapping for 0x%08llx"
> -		       " at 0x%08lx invalid alignment\n",
> -		       (long long)__pfn_to_phys((u64)md->pfn), addr);
> +		pr_err("MM: cannot create mapping for 0x%08llx at 0x%08lx invalid alignment\n",
> +			(long long)__pfn_to_phys((u64)md->pfn), addr);
>   		return;
>   	}
>
> @@ -764,18 +764,16 @@ static void __init create_mapping(struct map_desc *md)
>   	pgd_t *pgd;
>
>   	if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) {
> -		printk(KERN_WARNING "BUG: not creating mapping for 0x%08llx"
> -		       " at 0x%08lx in user region\n",
> -		       (long long)__pfn_to_phys((u64)md->pfn), md->virtual);
> +		pr_warn("BUG: not creating mapping for 0x%08llx at 0x%08lx in user region\n",
> +			(long long)__pfn_to_phys((u64)md->pfn), md->virtual);
>   		return;
>   	}
>
>   	if ((md->type == MT_DEVICE || md->type == MT_ROM) &&
>   	    md->virtual >= PAGE_OFFSET &&
>   	    (md->virtual < VMALLOC_START || md->virtual >= VMALLOC_END)) {
> -		printk(KERN_WARNING "BUG: mapping for 0x%08llx"
> -		       " at 0x%08lx out of vmalloc space\n",
> -		       (long long)__pfn_to_phys((u64)md->pfn), md->virtual);
> +		pr_warn("BUG: mapping for 0x%08llx at 0x%08lx out of vmalloc space\n",
> +				(long long)__pfn_to_phys((u64)md->pfn), md->virtual);
>   	}
>
>   	type = &mem_types[md->type];
> @@ -795,9 +793,8 @@ static void __init create_mapping(struct map_desc *md)
>   	length = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK));
>
>   	if (type->prot_l1 == 0 && ((addr | phys | length) & ~SECTION_MASK)) {
> -		printk(KERN_WARNING "BUG: map for 0x%08llx at 0x%08lx can not "
> -		       "be mapped using pages, ignoring.\n",
> -		       (long long)__pfn_to_phys(md->pfn), addr);
> +		pr_warn("BUG: map for 0x%08llx at 0x%08lx can not be mapped using pages, ignoring.\n",
> +			(long long)__pfn_to_phys(md->pfn), addr);
>   		return;
>   	}
>
> @@ -967,14 +964,14 @@ static int __init early_vmalloc(char *arg)
>
>   	if (vmalloc_reserve < SZ_16M) {
>   		vmalloc_reserve = SZ_16M;
> -		printk(KERN_WARNING
> +		pr_warn(
>   			"vmalloc area too small, limiting to %luMB\n",
>   			vmalloc_reserve >> 20);
>   	}
>
>   	if (vmalloc_reserve > VMALLOC_END - (PAGE_OFFSET + SZ_32M)) {
>   		vmalloc_reserve = VMALLOC_END - (PAGE_OFFSET + SZ_32M);
> -		printk(KERN_WARNING
> +		pr_warn(
>   			"vmalloc area is too big, limiting to %luMB\n",
>   			vmalloc_reserve >> 20);
>   	}
> @@ -984,7 +981,7 @@ static int __init early_vmalloc(char *arg)
>   }
>   early_param("vmalloc", early_vmalloc);
>
> -phys_addr_t arm_lowmem_limit __initdata = 0;
> +phys_addr_t arm_lowmem_limit __initdata;
>
>   void __init sanity_check_meminfo(void)
>   {
> @@ -1011,8 +1008,7 @@ void __init sanity_check_meminfo(void)
>   		if (!highmem && __va(bank->start) < vmalloc_min &&
>   		    bank->size > vmalloc_min - __va(bank->start)) {
>   			if (meminfo.nr_banks >= NR_BANKS) {
> -				printk(KERN_CRIT "NR_BANKS too low, "
> -						 "ignoring high memory\n");
> +				pr_crit("NR_BANKS too low, ignoring high memory\n");
>   			} else {
>   				memmove(bank + 1, bank,
>   					(meminfo.nr_banks - i) * sizeof(*bank));
> @@ -1032,10 +1028,9 @@ void __init sanity_check_meminfo(void)
>   		 * Highmem banks not allowed with !CONFIG_HIGHMEM.
>   		 */
>   		if (highmem) {
> -			printk(KERN_NOTICE "Ignoring RAM at %.8llx-%.8llx "
> -			       "(!CONFIG_HIGHMEM).\n",
> -			       (unsigned long long)bank->start,
> -			       (unsigned long long)bank->start + bank->size - 1);
> +			pr_notice("Ignoring RAM at %.8llx-%.8llx (!CONFIG_HIGHMEM).\n",
> +					(unsigned long long)bank->start,
> +					(unsigned long long)bank->start + bank->size - 1);
>   			continue;
>   		}
>
> @@ -1045,25 +1040,23 @@ void __init sanity_check_meminfo(void)
>   		 */
>   		if (__va(bank->start) >= vmalloc_min ||
>   		    __va(bank->start) < (void *)PAGE_OFFSET) {
> -			printk(KERN_NOTICE "Ignoring RAM at %.8llx-%.8llx "
> -			       "(vmalloc region overlap).\n",
> -			       (unsigned long long)bank->start,
> -			       (unsigned long long)bank->start + bank->size - 1);
> +			pr_notice("Ignoring RAM at %.8llx-%.8llx (vmalloc region overlap).\n",
> +				(unsigned long long)bank->start,
> +				(unsigned long long)bank->start + bank->size - 1);
>   			continue;
>   		}
>
>   		/*
> -		 * Check whether this memory bank would partially overlap
> -		 * the vmalloc area.
> -		 */
> +		* Check whether this memory bank would partially overlap
> +		* the vmalloc area.
> +		*/
>   		if (__va(bank->start + bank->size - 1) >= vmalloc_min ||
> -		    __va(bank->start + bank->size - 1) <= __va(bank->start)) {
> +				__va(bank->start + bank->size - 1) <= __va(bank->start)) {
>   			unsigned long newsize = vmalloc_min - __va(bank->start);
> -			printk(KERN_NOTICE "Truncating RAM at %.8llx-%.8llx "
> -			       "to -%.8llx (vmalloc region overlap).\n",
> -			       (unsigned long long)bank->start,
> -			       (unsigned long long)bank->start + bank->size - 1,
> -			       (unsigned long long)bank->start + newsize - 1);
> +			pr_notice("Truncating RAM at %.8llx-%.8llx to -%.8llx (vmalloc region overlap).\n",
> +				(unsigned long long)bank->start,
> +				(unsigned long long)bank->start + bank->size - 1,
> +				(unsigned long long)bank->start + newsize - 1);
>   			bank->size = newsize;
>   		}
>   #endif
> @@ -1085,7 +1078,7 @@ void __init sanity_check_meminfo(void)
>   			reason = "with VIPT aliasing cache";
>   		}
>   		if (reason) {
> -			printk(KERN_CRIT "HIGHMEM is not supported %s, ignoring high memory\n",
> +			pr_crit("HIGHMEM is not supported %s, ignoring high memory\n",
>   				reason);
>   			while (j > 0 && meminfo.bank[j - 1].highmem)
>   				j--;
> @@ -1112,7 +1105,7 @@ static inline void prepare_page_table(void)
>   	/* The XIP kernel is mapped in the module area -- skip over it */
>   	addr = ((unsigned long)_etext + PMD_SIZE - 1) & PMD_MASK;
>   #endif
> -	for ( ; addr < PAGE_OFFSET; addr += PMD_SIZE)
> +	for (; addr < PAGE_OFFSET; addr += PMD_SIZE)

Another cleanup, versus a functional change .. and there are other examples
that I didn't comment on.

Bruce

>   		pmd_clear(pmd_off_k(addr));
>
>   	/*
> @@ -1189,7 +1182,8 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
>   #ifdef CONFIG_XIP_KERNEL
>   	map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK);
>   	map.virtual = MODULES_VADDR;
> -	map.length = ((unsigned long)_etext - map.virtual + ~SECTION_MASK) & SECTION_MASK;
> +	map.length = ((unsigned long)_etext - map.virtual +
> +			~SECTION_MASK) & SECTION_MASK;
>   	map.type = MT_ROM;
>   	create_mapping(&map);
>   #endif
>



More information about the linux-yocto mailing list