All of lore.kernel.org
 help / color / mirror / Atom feed
From: r.sricharan@ti.com (Sricharan R)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH V6] ARM: LPAE: Fix mapping in alloc_init_section for unaligned addresses
Date: Mon, 18 Mar 2013 11:20:47 +0530	[thread overview]
Message-ID: <5146AB37.9060307@ti.com> (raw)
In-Reply-To: <CANOGCgPKwcDVVUBxbhKemTtvjye=3ZDP+wexfZfunt3BTJeerw@mail.gmail.com>

Hi Russell,

On Monday 18 March 2013 01:22 AM, Christoffer Dall wrote:
> On Sat, Mar 16, 2013 at 10:05 PM, Sricharan R <r.sricharan@ti.com> wrote:
>> From: R Sricharan <r.sricharan@ti.com>
>>
>> With LPAE enabled, alloc_init_section() does not map the entire
>> address space for unaligned addresses.
>>
>> The issue also reproduced with CMA + LPAE. CMA tries to map 16MB
>> with page granularity mappings during boot. alloc_init_pte()
>> is called and out of 16MB, only 2MB gets mapped and rest remains
>> unaccessible.
>>
>> Because of this OMAP5 boot is broken with CMA + LPAE enabled.
>> Fix the issue by ensuring that the entire addresses are
>> mapped.
>>
>> Signed-off-by: R Sricharan <r.sricharan@ti.com>
>> Cc: Catalin Marinas <catalin.marinas@arm.com>
>> Cc: Christoffer Dall <chris@cloudcar.com>
>> Cc: Russell King <linux@arm.linux.org.uk>
>> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
>> Tested-by: Laura Abbott <lauraa@codeaurora.org>
>> Acked-by: Catalin Marinas <catalin.marinas@arm.com>
>> ---
>>  [V2] Moved the loop to alloc_init_pte as per Russell's
>>      feedback and changed the subject accordingly.
>>      Using PMD_XXX instead of SECTION_XXX to avoid
>>      different loop increments with/without LPAE.
>>
>>  [v3] Removed the dummy variable phys and updated
>>       the commit log for CMA case.
>>
>>  [v4] Resending with updated change log and
>>       updating the tags.
>>
>>  [v5] Renamed alloc_init_section to alloc_init_pmd
>>       and moved the loop back there. Also introduced
>>       map_init_section as per Catalin's comments.
>>
>>  [v6] Corrected tags and updated the comments for code.
>>
>>  arch/arm/mm/mmu.c |   73 ++++++++++++++++++++++++++++++++++-------------------
>>  1 file changed, 47 insertions(+), 26 deletions(-)
>>
>> diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
>> index e95a996..7897894 100644
>> --- a/arch/arm/mm/mmu.c
>> +++ b/arch/arm/mm/mmu.c
>> @@ -598,39 +598,60 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
>>         } while (pte++, addr += PAGE_SIZE, addr != end);
>>  }
>>
>> -static void __init alloc_init_section(pud_t *pud, unsigned long addr,
>> -                                     unsigned long end, phys_addr_t phys,
>> -                                     const struct mem_type *type)
>> +static void __init map_init_section(pmd_t *pmd, unsigned long addr,
>> +                       unsigned long end, phys_addr_t phys,
>> +                       const struct mem_type *type)
>>  {
>> -       pmd_t *pmd = pmd_offset(pud, addr);
>> -
>> +#ifndef CONFIG_ARM_LPAE
>>         /*
>> -        * Try a section mapping - end, addr and phys must all be aligned
>> -        * to a section boundary.  Note that PMDs refer to the individual
>> -        * L1 entries, whereas PGDs refer to a group of L1 entries making
>> -        * up one logical pointer to an L2 table.
>> +        * In classic MMU format, puds and pmds are folded in to
>> +        * the pgds. pmd_offset gives the PGD entry. PGDs refer to a
>> +        * group of L1 entries making up one logical pointer to
>> +        * an L2 table (2MB), where as PMDs refer to the individual
>> +        * L1 entries (1MB). Hence increment to get the correct
>> +        * offset for odd 1MB sections.
>> +        * (See arch/arm/include/asm/pgtable-2level.h)
>>          */
>> -       if (type->prot_sect && ((addr | end | phys) & ~SECTION_MASK) == 0) {
>> -               pmd_t *p = pmd;
>> -
>> -#ifndef CONFIG_ARM_LPAE
>> -               if (addr & SECTION_SIZE)
>> -                       pmd++;
>> +       if (addr & SECTION_SIZE)
>> +               pmd++;
>>  #endif
>> +       do {
>> +               *pmd = __pmd(phys | type->prot_sect);
>> +               phys += SECTION_SIZE;
>> +       } while (pmd++, addr += SECTION_SIZE, addr != end);
>>
>> -               do {
>> -                       *pmd = __pmd(phys | type->prot_sect);
>> -                       phys += SECTION_SIZE;
>> -               } while (pmd++, addr += SECTION_SIZE, addr != end);
>> +       flush_pmd_entry(pmd);
>> +}
>>
>> -               flush_pmd_entry(p);
>> -       } else {
>> +static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
>> +                                     unsigned long end, phys_addr_t phys,
>> +                                     const struct mem_type *type)
>> +{
>> +       pmd_t *pmd = pmd_offset(pud, addr);
>> +       unsigned long next;
>> +
>> +       do {
>>                 /*
>> -                * No need to loop; pte's aren't interested in the
>> -                * individual L1 entries.
>> +                * With LPAE, we must loop over to map
>> +                * all the pmds for the given range.
>>                  */
>> -               alloc_init_pte(pmd, addr, end, __phys_to_pfn(phys), type);
>> -       }
>> +               next = pmd_addr_end(addr, end);
>> +
>> +               /*
>> +                * Try a section mapping - addr, next and phys must all be
>> +                * aligned to a section boundary.
>> +                */
>> +               if (type->prot_sect &&
>> +                               ((addr | next | phys) & ~SECTION_MASK) == 0) {
>> +                       map_init_section(pmd, addr, next, phys, type);
>> +               } else {
>> +                       alloc_init_pte(pmd, addr, next,
>> +                                               __phys_to_pfn(phys), type);
>> +               }
>> +
>> +               phys += next - addr;
>> +
>> +       } while (pmd++, addr = next, addr != end);
>>  }
>>
>>  static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
>> @@ -641,7 +662,7 @@ static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr,
>>
>>         do {
>>                 next = pud_addr_end(addr, end);
>> -               alloc_init_section(pud, addr, next, phys, type);
>> +               alloc_init_pmd(pud, addr, next, phys, type);
>>                 phys += next - addr;
>>         } while (pud++, addr = next, addr != end);
>>  }
>> --
>> 1.7.9.5
>>
> Acked-by: Christoffer Dall <chris@cloudcar.com>

I am not able to add this in to the patch system because my login fails.
I was trying using the credentials registered with linux-arm-kernel
 mailing list. Can you please help me here ?

Regards,
 Sricharan
 

  reply	other threads:[~2013-03-18  5:50 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-17  5:05 [PATCH V6] ARM: LPAE: Fix mapping in alloc_init_section for unaligned addresses Sricharan R
2013-03-17 19:52 ` Christoffer Dall
2013-03-18  5:50   ` Sricharan R [this message]
2013-03-18 10:45     ` Russell King - ARM Linux
2013-03-18 10:54       ` Sricharan R
  -- strict thread matches above, loose matches on Subject: below --
2013-02-11  9:13 R Sricharan
2013-02-11 13:12 ` Catalin Marinas
2013-02-11 13:23   ` R Sricharan
2013-02-11 13:52   ` R Sricharan
2013-02-21 12:26     ` R Sricharan
2013-03-14  3:58       ` Sricharan R
2013-03-15 17:36         ` Russell King - ARM Linux
2013-03-15 18:08           ` Christoffer Dall
2013-03-17  5:00             ` Sricharan R

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5146AB37.9060307@ti.com \
    --to=r.sricharan@ti.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.