[PATCH v5sub1 0/8] arm64: split linear and kernel mappings

Ard Biesheuvel ard.biesheuvel at linaro.org
Mon Feb 15 06:58:05 PST 2016


On 15 February 2016 at 14:29, Matthias Brugger <matthias.bgg at gmail.com> wrote:
>
>
> On 13/02/16 15:28, Ard Biesheuvel wrote:
>>
>> On 12 February 2016 at 21:10, Matthias Brugger <matthias.bgg at gmail.com>
>> wrote:
>>>
>>>
>>>
>>> On 12/02/16 20:47, Ard Biesheuvel wrote:
>>>>
>>>>
>>>> On 12 February 2016 at 20:45, Matthias Brugger <matthias.bgg at gmail.com>
>>>> wrote:
>>>>>
>>>>>
>>>>> Hi Ard,
>>>>>
>>>>>
>>>>> On 01/02/16 11:54, Ard Biesheuvel wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> At the request of Catalin, this series has been split off from my
>>>>>> series
>>>>>> 'arm64: implement support for KASLR v4' [1]. This sub-series deals
>>>>>> with
>>>>>> moving the kernel out of the linear mapping into the vmalloc area.
>>>>>> This
>>>>>> is a prerequisite for independent physical and virtual randomization
>>>>>> of
>>>>>> the kernel image. On top of that, considering that these changes allow
>>>>>> the linear mapping to start at an arbitrary offset above PAGE_OFFSET,
>>>>>> it
>>>>>> should be an improvement in itself due to the fact that we can now
>>>>>> choose
>>>>>> PAGE_OFFSET such that RAM can be mapped using large block sizes.
>>>>>>
>>>>>> For instance, on my Seattle A0 box, the kernel is loaded 16 MB into
>>>>>> the
>>>>>> lowest GB of RAM, which means __pa(PAGE_OFFSET) is not 1 GB aligned,
>>>>>> and
>>>>>> the entire 16 GB of RAM will be mapping using 2 MB blocks. (Similarly,
>>>>>> for 64 KB granule kernels, the entire 16 GB of RAM will be mapped
>>>>>> using
>>>>>> pages since __pa(PAGE_OFFSET) is not 512 MB aligned). With these
>>>>>> changes
>>>>>>     __pa(PAGE_OFFSET) will always be chosen such that it is aligned to
>>>>>> a
>>>>>> quantity that allows efficient mapping.
>>>>>>
>>>>>> Note that of the entire KASLR series, this sub-series is the most
>>>>>> likely
>>>>>> to
>>>>>> cause problems, and hence requires the most careful review and
>>>>>> testing.
>>>>>> This
>>>>>> is due to the fact that, with these changes, the invariant
>>>>>> __va(__pa(x))
>>>>>> == x
>>>>>> no longer holds, and any code that is based on that assumption needs
>>>>>> to
>>>>>> be
>>>>>> updated.
>>>>>>
>>>>>> Changes since v4:
>>>>>> - added Marc's ack to patch #6
>>>>>> - round the kasan zero shadow region around the kernel image to
>>>>>> swapper
>>>>>> block
>>>>>>      size (#7)
>>>>>> - ensure that we don't clip the kernel image when clipping RAM to the
>>>>>> linear
>>>>>>      region size (#8)
>>>>>>
>>>>>> Patch #1 allows the low mark of memblocks discovered from the FDT to
>>>>>> be
>>>>>> overridden by the architecture.
>>>>>>
>>>>>> Patch #2 enables the huge-vmap generic feature for arm64. This should
>>>>>> be
>>>>>> an
>>>>>> improvement in itself, but the significance for this series is that it
>>>>>> allows
>>>>>> unmap_kernel_range() to be called on the [__init_begin, __init_end)
>>>>>> region,
>>>>>> which may be partially mapped using block mappings.
>>>>>>
>>>>>> Patch #3 introduces KIMAGE_VADDR as a separate, preparatory step
>>>>>> towards
>>>>>> decoupling the kernel placement from PAGE_OFFSET
>>>>>>
>>>>>> Patch #4 implements some translation table accessors that operate on
>>>>>> statically
>>>>>> allocate translation tables before the linear mapping is up.
>>>>>>
>>>>>> Patch #5 decouples the fixmap initialization from the linear mapping,
>>>>>> by
>>>>>> using
>>>>>> the accessors implemented by patch #4
>>>>>>
>>>>>> Patch #6 removes assumptions made my KVM regarding the placement of
>>>>>> the
>>>>>> kernel
>>>>>> image inside the linear mapping.
>>>>>>
>>>>>> Patch #7 moves the kernel image from the base of the linear mapping to
>>>>>> the
>>>>>> base
>>>>>> of the vmalloc area. The modules area, which sits right below the
>>>>>> kernel
>>>>>> image,
>>>>>> is moved along and is put right before the start of the vmalloc area.
>>>>>>
>>>>>> Patch #8 decouples PHYS_OFFSET from PAGE_OFFSET, which allows the
>>>>>> linear
>>>>>> mapping
>>>>>> to cover all discovered memory, regardless of where the kernel image
>>>>>> is
>>>>>> located
>>>>>> in it. This effectively allows the kernel to be loaded at any physical
>>>>>> address
>>>>>> (provided that the correct alignment is used)
>>>>>>
>>>>>> [1] http://thread.gmane.org/gmane.linux.kernel/2135931
>>>>>>
>>>>>> Ard Biesheuvel (8):
>>>>>>      of/fdt: make memblock minimum physical address arch configurable
>>>>>>      arm64: add support for ioremap() block mappings
>>>>>>      arm64: introduce KIMAGE_VADDR as the virtual base of the kernel
>>>>>> region
>>>>>>      arm64: pgtable: implement static [pte|pmd|pud]_offset variants
>>>>>>      arm64: decouple early fixmap init from linear mapping
>>>>>>      arm64: kvm: deal with kernel symbols outside of linear mapping
>>>>>>      arm64: move kernel image to base of vmalloc area
>>>>>>      arm64: allow kernel Image to be loaded anywhere in physical
>>>>>> memory
>>>>>>
>>>>>
>>>>> I bisected linux-next (20160212) with the following error on booting
>>>>> with
>>>>> an
>>>>> initramfs:
>>>>>    Failed to execute /init (error -8)
>>>>>    request_module: runaway loop modprobe binfmt-464c
>>>>>    Starting init: /sbin/init exists but couldn't execute it (error -8)
>>>>>    request_module: runaway loop modprobe binfmt-464c
>>>>>    Starting init: /bin/sh exists but couldn't execute it (error -8)
>>>>>    Kernel panic - not syncing: No working init found.  Try passing
>>>>> init=
>>>>> option to kernel. See Linux Documentation/init..
>>>>>
>>>>> I tracked down the error to patch 7 of this series. But I realized that
>>>>> patch 7 does not compile, but from patch 8 onwards I observe the error.
>>>>>
>>
>> As far as this failure is concerned, I managed to reproduce an error
>> with patch #7 and not #8 applied, involving out of range kvm symbols
>> at link time. This is reproducible with GCC 4.8 but not GCC 4.9 or
>> later. Is this what you were seeing as well? Or is there another
>> problem?
>>
>
> I realized that I used " aarch64-linux-gnu-gcc (Linaro GCC 2014.11) 4.9.3
> 20141031 (prerelease)"  which gave me errors like:
>
> arch/arm64/kvm/built-in.o: In function `__cpu_init_hyp_mode':
> /home/mbrugger/src/linux-next/./arch/arm64/include/asm/kvm_host.h:331:(.text+0x73b4):
> relocation truncated to fit: R_AARCH64_ADR_PREL_PG_HI21 against symbol
> `__kvm_hyp_vector' defined in .hyp.text section in arch/arm64/kvm/built-in.o
>
> So it was time to update my toolchain to "aarch64-linux-gnu-gcc (Linaro GCC
> 5.1-2015.08) 5.1.1 20150608" which fixed the problem for me.
>

OK, so it's the same issue, but I thought before that 4.9 worked ok,
which is indeed not the case (I checked)
This is a transient issue, since the subsequent patch replaces the
offending expressions, but to maintain bisectability, I will add a
workaround nonetheless.

Thanks,
Ard.



More information about the linux-arm-kernel mailing list