On 14-03-20 06:14 AM, Anders Berg wrote:
On Thu, Mar 20, 2014 at 04:48:27AM -0400, Bruce Ashfield wrote:
On 14-03-18 03:49 AM, Charlie Paul wrote:
From: Anders Berg <anders.b...@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.

arm/mmu: Fix detection of vmalloc area overlap

Fix problem when passing mem=4G (or 4GB memory specified on the device tree
memory node) when running without CONFIG_HIGHMEM . In this case, the test for
vmalloc area overlap would fail (because of a 32-bit overflow) and the memory
block would not be properly truncated to a lowmem compliant size.

Same comment here. When we change a common file, the change must be suitable
for all boards.

Is this safe for all 32 bit ARM boards ? Is it destined for mainline ?


This was originally two commits. Both have been fixed upstream:

20d6956 ARM: LPAE: use phys_addr_t in alloc_init_pud()
36418c5 ARM: 7499/1: mm: Fix vmalloc overlap check for !HIGHMEM

Aha. This is important, it shows that the changes are indeed safe and
reviewed upstream.

Can we split this back into the upstream commit granularity and link to
the upstream commits in the message.

Bruce


Charile: What's up with all the white-space changes (and what looks like
checkpatch cleanups). This was not in my original commit(s)?

/Anders

Bruce


Signed-off-by: Anders Berg <anders.b...@lsi.com>
---
  arch/arm/mm/mmu.c |   82 +++++++++++++++++++++++------------------------------
  1 file changed, 36 insertions(+), 46 deletions(-)

diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index f117e1f..6ccd654 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -53,13 +53,13 @@ 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;
-pgprot_t pgprot_kernel;
-
  EXPORT_SYMBOL(pgprot_user);
+pgprot_t pgprot_kernel;
  EXPORT_SYMBOL(pgprot_kernel);

+
  struct cachepolicy {
        const char      policy[16];
        unsigned int    cr_mask;
@@ -194,8 +194,8 @@ void adjust_cr(unsigned long mask, unsigned long set)
  }
  #endif

-#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 */
@@ -216,7 +216,7 @@ static struct mem_type mem_types[] = {
                .prot_l1        = PMD_TYPE_TABLE,
                .prot_sect      = PROT_SECT_DEVICE | PMD_SECT_WB,
                .domain         = DOMAIN_IO,
-       },      
+       },
        [MT_DEVICE_WC] = {      /* ioremap_wc */
                .prot_pte       = PROT_PTE_DEVICE | L_PTE_MT_DEV_WC,
                .prot_l1        = PMD_TYPE_TABLE,
@@ -532,7 +532,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",
+       printk(KERN_INFO "Memory policy: ECC %sabled, Data cache %s\n",
                ecc_mask ? "en" : "dis", cp->policy);

        for (i = 0; i < ARRAY_SIZE(mem_types); i++) {
@@ -628,7 +628,7 @@ static void __init alloc_init_section(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;
@@ -653,9 +653,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);
+               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);
                return;
        }

@@ -666,16 +665,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);
+               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);
                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);
+               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);
                return;
        }

@@ -717,18 +714,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);
+               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);
                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);
+               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);
        }

        type = &mem_types[md->type];
@@ -748,9 +743,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);
+               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);
                return;
        }

@@ -783,8 +777,8 @@ void __init iotable_init(struct map_desc *io_desc, int nr)
                create_mapping(md);
                vm->addr = (void *)(md->virtual & PAGE_MASK);
                vm->size = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK));
-               vm->phys_addr = __pfn_to_phys(md->pfn);
-               vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING;
+               vm->phys_addr = __pfn_to_phys(md->pfn);
+               vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING;
                vm->flags |= VM_ARM_MTYPE(md->type);
                vm->caller = iotable_init;
                vm_area_add_early(vm++);
@@ -895,7 +889,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)
  {
@@ -922,8 +916,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");
+                               printk(KERN_CRIT "NR_BANKS too low, ignoring high 
memory\n");
                        } else {
                                memmove(bank + 1, bank,
                                        (meminfo.nr_banks - i) * sizeof(*bank));
@@ -943,10 +936,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);
+                       printk(KERN_NOTICE "Ignoring RAM at %.8llx-%.8llx 
(!CONFIG_HIGHMEM).\n",
+                                       (unsigned long long)bank->start,
+                                       (unsigned long long)bank->start + 
bank->size - 1);
                        continue;
                }

@@ -956,10 +948,9 @@ 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);
+                       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);
                        continue;
                }

@@ -967,14 +958,13 @@ void __init sanity_check_meminfo(void)
                 * Check whether this memory bank would partially overlap
                 * the vmalloc area.
                 */
-               if (__va(bank->start + bank->size) > vmalloc_min ||
-                   __va(bank->start + bank->size) < __va(bank->start)) {
+               if (__va(bank->start + bank->size -1) >= vmalloc_min ||
+                   __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);
+                       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);
                        bank->size = newsize;
                }
  #endif




--
_______________________________________________
linux-yocto mailing list
linux-yocto@yoctoproject.org
https://lists.yoctoproject.org/listinfo/linux-yocto

Reply via email to