[PATCH 07/12] arm64: mm: Place kImage at bottom of VA space

Ard Biesheuvel ard.biesheuvel at linaro.org
Mon Dec 4 08:25:18 PST 2017


On 4 December 2017 at 14:13, Steve Capper <steve.capper at arm.com> wrote:
> Re-arrange the kernel memory map s.t. the kernel image resides in the
> bottom 514MB of memory.

I guess this breaks KASLR entirely, no? Given that it adds an offset
in the range [0 ... sizeof(VMALLOC_SPACE) /4 ].

In any case, it makes sense to keep the kernel VA space adjacent to
the VMALLOC space, rather than put stuff like PCI I/O and the fixmap
in between.

> With the modules, fixed map, PCI IO space placed
> above it. At the very bottom of the memory map we set aside a 2MB guard
> region to prevent ambiguity with PTR_ERR/ERR_PTR.
>

Interesting. In another thread, we discussed whether it is necessary
to prevent the linear map randomization code from allocating at the
very top [bottom in Steve-speak] of the kernel virtual address space,
and this is a thing I did not consider.

> Dynamically resizable objects such as KASAN shadow and sparsemem map
> are placed above the fixed size objects.
>

The current placement of the sparsemem map was carefully chosen so
that virt_to_page/page_to_virt translations are extremely cheap. Is
that still the case?

> This means that kernel addresses are now no longer directly dependent on
> VA space size.
>
> Signed-off-by: Steve Capper <steve.capper at arm.com>
> ---
>  arch/arm64/include/asm/memory.h  | 17 +++++++++--------
>  arch/arm64/include/asm/pgtable.h |  4 ++--
>  arch/arm64/mm/dump.c             | 12 +++++++-----
>  3 files changed, 18 insertions(+), 15 deletions(-)
>
> diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
> index 0a912eb3d74f..ba80561c6ed8 100644
> --- a/arch/arm64/include/asm/memory.h
> +++ b/arch/arm64/include/asm/memory.h
> @@ -68,14 +68,15 @@
>  #define PAGE_OFFSET            (UL(0xffffffffffffffff) - \
>         (UL(1) << VA_BITS) + 1)
>  #define PAGE_OFFSET_END                (VA_START)
> -#define KIMAGE_VADDR           (MODULES_END)
> -#define MODULES_END            (MODULES_VADDR + MODULES_VSIZE)
> -#define MODULES_VADDR          (VA_START + KASAN_SHADOW_SIZE)
> +#define KIMAGE_VSIZE           (SZ_512M)
> +#define KIMAGE_VADDR           (UL(0) - SZ_2M - KIMAGE_VSIZE)
>  #define MODULES_VSIZE          (SZ_128M)
> -#define VMEMMAP_START          (-VMEMMAP_SIZE)
> -#define PCI_IO_END             (VMEMMAP_START - SZ_2M)
> +#define MODULES_END            (KIMAGE_VADDR)
> +#define MODULES_VADDR          (MODULES_END - MODULES_VSIZE)
> +#define PCI_IO_END             (MODULES_VADDR - SZ_2M)
>  #define PCI_IO_START           (PCI_IO_END - PCI_IO_SIZE)
> -#define FIXADDR_TOP            (PCI_IO_START - SZ_2M)
> +#define FIXADDR_TOP            (PCI_IO_START - PGDIR_SIZE)
> +#define VMEMMAP_START          (FIXADDR_START - VMEMMAP_SIZE)
>
>  #define KERNEL_START      _text
>  #define KERNEL_END        _end
> @@ -292,10 +293,10 @@ static inline void *phys_to_virt(phys_addr_t x)
>  #define _virt_addr_valid(kaddr)        pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
>  #else
>  #define __virt_to_pgoff(kaddr) (((u64)(kaddr) & ~PAGE_OFFSET) / PAGE_SIZE * sizeof(struct page))
> -#define __page_to_voff(kaddr)  (((u64)(kaddr) & ~VMEMMAP_START) * PAGE_SIZE / sizeof(struct page))
> +#define __page_to_voff(kaddr)  (((u64)(kaddr) - VMEMMAP_START) * PAGE_SIZE / sizeof(struct page))
>
>  #define page_to_virt(page)     ((void *)((__page_to_voff(page)) | PAGE_OFFSET))
> -#define virt_to_page(vaddr)    ((struct page *)((__virt_to_pgoff(vaddr)) | VMEMMAP_START))
> +#define virt_to_page(vaddr)    ((struct page *)((__virt_to_pgoff(vaddr)) + VMEMMAP_START))
>
>  #define _virt_addr_valid(kaddr)        pfn_valid((((u64)(kaddr) & ~PAGE_OFFSET) \
>                                            + PHYS_OFFSET) >> PAGE_SHIFT)
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 054b37143a50..e8b4dcc11fed 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -30,8 +30,8 @@
>   * VMALLOC_END: extends to the available space below vmmemmap, PCI I/O space
>   *     and fixed mappings
>   */
> -#define VMALLOC_START          (MODULES_END)
> -#define VMALLOC_END            (- PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
> +#define VMALLOC_START          (VA_START + KASAN_SHADOW_SIZE)
> +#define VMALLOC_END            (FIXADDR_TOP - PUD_SIZE)
>
>  #define vmemmap                        ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT))
>
> diff --git a/arch/arm64/mm/dump.c b/arch/arm64/mm/dump.c
> index b7b09c0fc50d..e5d1b5f432fe 100644
> --- a/arch/arm64/mm/dump.c
> +++ b/arch/arm64/mm/dump.c
> @@ -36,17 +36,19 @@ static const struct addr_marker address_markers[] = {
>         { KASAN_SHADOW_START,           "Kasan shadow start" },
>         { KASAN_SHADOW_END,             "Kasan shadow end" },
>  #endif
> -       { MODULES_VADDR,                "Modules start" },
> -       { MODULES_END,                  "Modules end" },
>         { VMALLOC_START,                "vmalloc() Area" },
>         { VMALLOC_END,                  "vmalloc() End" },
> +#ifdef CONFIG_SPARSEMEM_VMEMMAP
> +       { VMEMMAP_START,                "vmemmap start" },
> +       { VMEMMAP_START + VMEMMAP_SIZE, "vmemmap end"},
> +#endif
>         { FIXADDR_START,                "Fixmap start" },
>         { FIXADDR_TOP,                  "Fixmap end" },
>         { PCI_IO_START,                 "PCI I/O start" },
>         { PCI_IO_END,                   "PCI I/O end" },
> -#ifdef CONFIG_SPARSEMEM_VMEMMAP
> -       { VMEMMAP_START,                "vmemmap" },
> -#endif
> +       { MODULES_VADDR,                "Modules start" },
> +       { MODULES_END,                  "Modules end" },
> +       { KIMAGE_VADDR,                 "kImage start"},
>         { -1,                           NULL },
>  };
>
> --
> 2.11.0
>



More information about the linux-arm-kernel mailing list