From: "Russell King (Oracle)" <linux@armlinux.org.uk>
To: Linus Walleij <linus.walleij@linaro.org>
Cc: Grygorii Strashko <grygorii.strashko@ti.com>,
Nishanth Menon <nm@ti.com>,
santosh.shilimkar@oracle.com,
Santosh Shilimkar <ssantosh@kernel.org>,
Linux ARM <linux-arm-kernel@lists.infradead.org>,
Arnd Bergmann <arnd@arndb.de>,
Florian Fainelli <f.fainelli@gmail.com>,
Geert Uytterhoeven <geert+renesas@glider.be>,
Ard Biesheuvel <ardb@kernel.org>, Suman Anna <s-anna@ti.com>,
Tero Kristo <kristo@kernel.org>
Subject: Re: [PATCH 3/3] ARM: Map the lowmem and kernel separately
Date: Wed, 4 Aug 2021 11:36:58 +0100 [thread overview]
Message-ID: <20210804103658.GP22278@shell.armlinux.org.uk> (raw)
In-Reply-To: <CACRpkdaOub9EJFGy8+kWLN13wq2V_XSXrnrfxiUCvb6gdWKmBg@mail.gmail.com>
On Wed, Aug 04, 2021 at 12:05:54PM +0200, Linus Walleij wrote:
> On Tue, Aug 3, 2021 at 12:49 PM Russell King (Oracle)
> <linux@armlinux.org.uk> wrote:
>
> > > It should be called on all keystone 2 platforms by default (LAPE is default mode for K2).
> > >
> > > Huh. Below as I remember it:
> > > - K2 starts using memory window (aliased memory) at 00 8000 0000 (No IO coherency is supported)
> > > - K2, early at boot, is switching to LPAE memory window 08 0000 0000 (IO coherency is supported)
> > > so all, already mapped memory, has to be fixed - phys addresses.
> >
> > If I remember correctly, the code that fixes that up assumes that
> > (a) the kernel is mapped using section mappings in the lowmem mapping
> > at PAGE_OFFSET.._end-1
> > (b) that no other RAM is mapped (iow, it's called before the kernel
> > starts building the real page mappings in paging_init()).
> >
> > It looks to me like Linus missed the code in arch/arm/mm/pv-fixup-asm.S
> > and as the kernel is no longer mapped in the lowmem mapping, this
> > likely writes a load of entries in the page tables that are random...
>
> I looked into this!
>
> Indeed early_mm_init() is called before paging_init() and early_mm_init()
> calls lpae_pgtables_remap_asm() in pv-fixup-asm.S to add the offset
> to all the section mappings over the kernel.
>
> The section mappings we have at this point are coming from head.S,
> so those get modified with the offset.
>
> What I don't understand is what map_lowmem() was doing with the
> kernel mappings on the Keystone 2 before my patch.
Essentially, what happened with Keystone 2 is that the head.S code
does its usual thing, mapping the kernel using the physical address
that the early code is running at using section mappings, before
then switching the MMU on and running from the virtual address space.
At this point, the phys<->virt conversions work for this physical
address space (which, on Keystone 2 is the low physical space which
isn't coherent with devices.)
early_mm_init() gets called, we spot we're on Keystone 2, and we
initiate the change - the MMU needs a break-before-make for these
mappings, and as we're using these mappings to execute our code,
we have to turn the MMU off to do the update.
We update the phys<->virt conversion, and then fixup the page
tables. lpae_pgtables_remap() is passed the offset between the
low physical address and the high physical address, as well as the
low physical address of the page tables. (since when we turn the MMU
off, all we have access to are the low physical mapping.)
The structure of the LPAE page tables is:
- First 4k - L1 entries.
- Following 32k - L2 entries mapped as sections.
In pv-fixup-asm.S:
ldr r6, =(_end - 1)
add r7, r2, #0x1000
add r6, r7, r6, lsr #SECTION_SHIFT - L2_ORDER
add r7, r7, #PAGE_OFFSET >> (SECTION_SHIFT - L2_ORDER)
r7 is the low physical address in the L2 entries, r6 is the last
(inclusive) entry. Essentially, all we do is add "offset" to every
section mapping corresponding to addresses between PAGE_OFFSET and
_end.
We also do that for the boot data (two section mappings) at
FDT_FIXED_BASE, the four L1 entries, and the two TTBR physical
address register values.
> If it actually overwrites the kernel mapping with a new one, it will
> undo what lpae_pgtables_remap_asm() has done without applying
> the offset.
>
> So I suppose map_lowmem(), due to the memory ranges passed,
> would just bail the kernel mappings and leave them as-is.
By the time map_lowmem() gets called, the phys<->virt mappings will
have been modified throughout the kernel so that virtual addresses
in the direct mapping will translate to the high physical addresses.
So, things like __pa(__init_end) in map_kernel() will translate
__init_end to the high physical address rather than the low physical
address.
My guess would be the problem is that kernel_sec_start and
kernel_sec_end are not being adjusted, and are still pointing at
the low physical addresses rather than the high ones.
Consequently, kernel_x_start and kernel_nx_end points at the low phys
space, but kernel_x_end and kernel_nx_start points to the high phys
space.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2021-08-04 10:39 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-05-17 14:57 [PATCH 0/3] Split lowmem and kernel mappings Linus Walleij
2021-05-17 14:57 ` [PATCH 1/3] ARM: Split KERNEL_OFFSET from PAGE_OFFSET Linus Walleij
2021-05-17 14:57 ` [PATCH 2/3] ARM: Define kernel physical section start and end Linus Walleij
2021-05-17 14:57 ` [PATCH 3/3] ARM: Map the lowmem and kernel separately Linus Walleij
2021-07-30 20:22 ` Nishanth Menon
2021-07-30 22:40 ` Linus Walleij
2021-08-03 10:27 ` Grygorii Strashko
2021-08-03 10:49 ` Russell King (Oracle)
2021-08-03 11:34 ` Linus Walleij
2021-08-04 10:05 ` Linus Walleij
2021-08-04 10:36 ` Russell King (Oracle) [this message]
2021-08-04 13:12 ` Linus Walleij
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=20210804103658.GP22278@shell.armlinux.org.uk \
--to=linux@armlinux.org.uk \
--cc=ardb@kernel.org \
--cc=arnd@arndb.de \
--cc=f.fainelli@gmail.com \
--cc=geert+renesas@glider.be \
--cc=grygorii.strashko@ti.com \
--cc=kristo@kernel.org \
--cc=linus.walleij@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=nm@ti.com \
--cc=s-anna@ti.com \
--cc=santosh.shilimkar@oracle.com \
--cc=ssantosh@kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).