From mboxrd@z Thu Jan 1 00:00:00 1970 From: r.sricharan@ti.com (R Sricharan) Date: Wed, 6 Feb 2013 19:26:12 +0530 Subject: [PATCH v4] ARM: LPAE: Fix mapping in alloc_init_pte for unaligned addresses In-Reply-To: <20130206121523.GD26454@arm.com> References: <1359472036-7613-1-git-send-email-r.sricharan@ti.com> <20130201162631.GG5151@arm.com> <20130201163722.GH5151@arm.com> <20130201174246.GJ5151@arm.com> <510F3BA8.8070700@ti.com> <510F3CA3.7080604@ti.com> <20130206121523.GD26454@arm.com> Message-ID: <511260FC.2090002@ti.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org On Wednesday 06 February 2013 05:45 PM, Catalin Marinas wrote: > On Mon, Feb 04, 2013 at 04:44:19AM +0000, R Sricharan wrote: >> On Monday 04 February 2013 10:10 AM, R Sricharan wrote: >>>> diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c >>>> index 9f06102..47154f3 100644 >>>> --- a/arch/arm/mm/mmu.c >>>> +++ b/arch/arm/mm/mmu.c >>>> @@ -581,34 +581,36 @@ static void __init alloc_init_section(pud_t >>>> *pud, unsigned long addr, >>>> const struct mem_type *type) >>>> { >>>> pmd_t *pmd = pmd_offset(pud, addr); >>>> + unsigned long next; >>>> >>>> - /* >>>> - * 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. >>>> - */ >>>> - if (type->prot_sect && ((addr | end | phys) & ~SECTION_MASK) == 0) { >>>> - pmd_t *p = pmd; >>>> + do { >>>> + next = pmd_addr_end(addr, end); >>>> + >>>> + /* >>>> + * Try a section mapping - next, 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. >>>> + */ >>>> + if (((addr | next | phys) & ~SECTION_MASK) == 0) { >>>> + pmd_t *p = pmd; >>>> >>> There is a need to do page mappings even when all the addresses >>> are aligned. This was added with CMA, which required the initial >>> mappings to be set with 2 level tables. >>> >> Sorry, i wanted to ask type->prot_sect is removed here and is that >> intentional? > > No, I just forgot about it. > >> I did a similar kind of patch in my V1 [1]. >> I should be using PMD_MASK instead of SECTION_MASK there, and >> updated it in the next version. >> >> [1] https://patchwork.kernel.org/patch/1272991/ > > With regards to your current patch, I really don't think looping over > pmd in alloc_init_pte() is the right fix. The alloc_init_pte() function > gets a pmd argument and it is supposed to make it point to a pte and > populate that pte rather than populate a number of pmds. > > create_mapping() loops over pgds. alloc_init_pud() loops over puds > (well, we don't have any but we have the function for consistency). > alloc_init_section() should loop over pmds (we can even change the name > to alloc_init_pmd()). > > Your original patch from August was better as it kept the looping > consistent but as you said, it should be using pmd_addr_end(). We can > use something simpler like alloc_init_pmd() on arm64 and instead of > set_pmd() there just call a separate map_init_section() which for > 2-levels it sets both entries. This may address Russell's comment that > the resulting code was ugly. Thanks. So just to understand, you mean alloc_init_pmd loops over map_init_section. map_init_section populates either one pmd or calls alloc_init_pte. correct ? . I can send a v5 for this. > > The problem with the classic MMU is that if we have a 1MB range we can > end up with just page mappings. The code is currently buggy since if we > have create_mapping() for a 1MB range and later create_mapping() for a > 4KB in the next MB, the first 1MB is removed. > Ok, so in that case we will have a BUG_ON(pmd_bad) right? Earlier we had this hit when both static and page mappings were attempted in the same 2MB range and understood it was wrong. Regards, Sricharan