[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