[PATCH 2/2] ARM: LPAE: reduce damage caused by idmap to virtual memory layout

Konstantin Khlebnikov koct9i at gmail.com
Mon Jul 28 12:29:39 PDT 2014


On Mon, Jul 28, 2014 at 11:13 PM, Russell King - ARM Linux
<linux at arm.linux.org.uk> wrote:
> On Mon, Jul 28, 2014 at 10:57:00PM +0400, Konstantin Khlebnikov wrote:
>> Also I seen comment somewhere in the code which tells that idrmap pgd is
>> always below 4gb which isn't quite true.
>
> "idmap" means "identity map".  It's a region which maps the same value of
> physical address to the same value of virtual address.
>
> Since the virtual address space is limited to 4GB, there is /no way/ that
> the physical address can be above 4GB, and it still be called an
> "identity map".
>
> The reason for this is that code in the identity map will be fetched with
> the MMU off.  While this code is running, it will enable the MMU using the
> identity map page table pointer, and the CPU must see _no_ change in the
> instructions/data fetched from that region.  It will then branch to the
> kernel proper, and the kernel will then switch away from the identity page
> table.
>
> Once the kernel has switched away from the identity page table, interrupts
> and other exceptions can then be taken on the CPU - but not before.
> Neither is it expected that the CPU will access any devices until it has
> switched away from the identity page table.
>
> What this also means is that the code in the identity map must remain
> visible in the low 4GB of physical address space.

Ok, before switching from identity mapping to normal mapping kernel must
switch instruction pointer from physical address to virtual. It's a long jump
out idmap code section to some normal kernel function.
__secondary_switched in my case. And both physical source and virtual
destination addresses must present in one same mapping (idmap).

idmap pgd starts as copy of pgd from init_mm, it points to the same pmd pages.
When it populates identical mapping for that special code section it allocates
new pages from pmd entries (which covers 1Gb of vm layout) but only few of
them are filled. In case 3/1GB split If idmap touches somehing above 3Gb it
kills whole kernel vm layout and as result kernel cannot jump to any
virtual address.

>
>> Moreover, I had some experiments with
>> mapping ram to random places in qemu and seen that kernel cannot boot if
>> PHYS_OFFSET isn't alligned to 128mb which is strange.
>
> That is intentional.  PHYS_OFFSET has a number of restrictions, one of
> them is indeed that the physical offset /will/ be aligned to 128MB.
> That was decided after looking at the platforms we have and is now
> fixed at that value with platform-breaking consequences if it needs
> changing.
>
> --
> FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
> according to speedtest.net.



More information about the linux-arm-kernel mailing list