Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f9040773 authored by Ard Biesheuvel's avatar Ard Biesheuvel Committed by Catalin Marinas
Browse files

arm64: move kernel image to base of vmalloc area



This moves the module area to right before the vmalloc area, and moves
the kernel image to the base of the vmalloc area. This is an intermediate
step towards implementing KASLR, which allows the kernel image to be
located anywhere in the vmalloc area.

Since other subsystems such as hibernate may still need to refer to the
kernel text or data segments via their linears addresses, both are mapped
in the linear region as well. The linear alias of the text region is
mapped read-only/non-executable to prevent inadvertent modification or
execution.

Signed-off-by: default avatarArd Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent a0bf9776
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@
 * KASAN_SHADOW_END: KASAN_SHADOW_START + 1/8 of kernel virtual addresses.
 */
#define KASAN_SHADOW_START      (VA_START)
#define KASAN_SHADOW_END        (KASAN_SHADOW_START + (1UL << (VA_BITS - 3)))
#define KASAN_SHADOW_END        (KASAN_SHADOW_START + KASAN_SHADOW_SIZE)

/*
 * This value is used to map an address to the corresponding shadow
+15 −6
Original line number Diff line number Diff line
@@ -45,16 +45,15 @@
 * VA_START - the first kernel virtual address.
 * TASK_SIZE - the maximum size of a user space task.
 * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area.
 * The module space lives between the addresses given by TASK_SIZE
 * and PAGE_OFFSET - it must be within 128MB of the kernel text.
 */
#define VA_BITS			(CONFIG_ARM64_VA_BITS)
#define VA_START		(UL(0xffffffffffffffff) << VA_BITS)
#define PAGE_OFFSET		(UL(0xffffffffffffffff) << (VA_BITS - 1))
#define KIMAGE_VADDR		(PAGE_OFFSET)
#define MODULES_END		(KIMAGE_VADDR)
#define MODULES_VADDR		(MODULES_END - SZ_64M)
#define PCI_IO_END		(MODULES_VADDR - SZ_2M)
#define KIMAGE_VADDR		(MODULES_END)
#define MODULES_END		(MODULES_VADDR + MODULES_VSIZE)
#define MODULES_VADDR		(VA_START + KASAN_SHADOW_SIZE)
#define MODULES_VSIZE		(SZ_64M)
#define PCI_IO_END		(PAGE_OFFSET - SZ_2M)
#define PCI_IO_START		(PCI_IO_END - PCI_IO_SIZE)
#define FIXADDR_TOP		(PCI_IO_START - SZ_2M)
#define TASK_SIZE_64		(UL(1) << VA_BITS)
@@ -71,6 +70,16 @@

#define TASK_UNMAPPED_BASE	(PAGE_ALIGN(TASK_SIZE / 4))

/*
 * The size of the KASAN shadow region. This should be 1/8th of the
 * size of the entire kernel virtual address space.
 */
#ifdef CONFIG_KASAN
#define KASAN_SHADOW_SIZE	(UL(1) << (VA_BITS - 3))
#else
#define KASAN_SHADOW_SIZE	(0)
#endif

/*
 * Physical vs virtual RAM address space conversion.  These are
 * private definitions which should NOT be used outside memory.h
+2 −8
Original line number Diff line number Diff line
@@ -36,19 +36,13 @@
 *
 * VMEMAP_SIZE: allows the whole VA space to be covered by a struct page array
 *	(rounded up to PUD_SIZE).
 * VMALLOC_START: beginning of the kernel VA space
 * VMALLOC_START: beginning of the kernel vmalloc space
 * VMALLOC_END: extends to the available space below vmmemmap, PCI I/O space,
 *	fixed mappings and modules
 */
#define VMEMMAP_SIZE		ALIGN((1UL << (VA_BITS - PAGE_SHIFT)) * sizeof(struct page), PUD_SIZE)

#ifndef CONFIG_KASAN
#define VMALLOC_START		(VA_START)
#else
#include <asm/kasan.h>
#define VMALLOC_START		(KASAN_SHADOW_END + SZ_64K)
#endif

#define VMALLOC_START		(MODULES_END)
#define VMALLOC_END		(PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K)

#define vmemmap			((struct page *)(VMALLOC_END + SZ_64K))
+6 −6
Original line number Diff line number Diff line
@@ -35,7 +35,9 @@ struct addr_marker {
};

enum address_markers_idx {
	VMALLOC_START_NR = 0,
	MODULES_START_NR = 0,
	MODULES_END_NR,
	VMALLOC_START_NR,
	VMALLOC_END_NR,
#ifdef CONFIG_SPARSEMEM_VMEMMAP
	VMEMMAP_START_NR,
@@ -45,12 +47,12 @@ enum address_markers_idx {
	FIXADDR_END_NR,
	PCI_START_NR,
	PCI_END_NR,
	MODULES_START_NR,
	MODULES_END_NR,
	KERNEL_SPACE_NR,
};

static struct addr_marker address_markers[] = {
	{ MODULES_VADDR,	"Modules start" },
	{ MODULES_END,		"Modules end" },
	{ VMALLOC_START,	"vmalloc() Area" },
	{ VMALLOC_END,		"vmalloc() End" },
#ifdef CONFIG_SPARSEMEM_VMEMMAP
@@ -61,9 +63,7 @@ static struct addr_marker address_markers[] = {
	{ FIXADDR_TOP,		"Fixmap end" },
	{ PCI_IO_START,		"PCI I/O start" },
	{ PCI_IO_END,		"PCI I/O end" },
	{ MODULES_VADDR,	"Modules start" },
	{ MODULES_END,		"Modules end" },
	{ PAGE_OFFSET,		"Kernel Mapping" },
	{ PAGE_OFFSET,		"Linear Mapping" },
	{ -1,			NULL },
};

+12 −11
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@
#include <linux/swiotlb.h>

#include <asm/fixmap.h>
#include <asm/kasan.h>
#include <asm/memory.h>
#include <asm/sections.h>
#include <asm/setup.h>
@@ -302,22 +303,26 @@ void __init mem_init(void)
#ifdef CONFIG_KASAN
		  "    kasan   : 0x%16lx - 0x%16lx   (%6ld GB)\n"
#endif
		  "    modules : 0x%16lx - 0x%16lx   (%6ld MB)\n"
		  "    vmalloc : 0x%16lx - 0x%16lx   (%6ld GB)\n"
		  "      .init : 0x%p" " - 0x%p" "   (%6ld KB)\n"
		  "      .text : 0x%p" " - 0x%p" "   (%6ld KB)\n"
		  "      .data : 0x%p" " - 0x%p" "   (%6ld KB)\n"
#ifdef CONFIG_SPARSEMEM_VMEMMAP
		  "    vmemmap : 0x%16lx - 0x%16lx   (%6ld GB maximum)\n"
		  "              0x%16lx - 0x%16lx   (%6ld MB actual)\n"
#endif
		  "    fixed   : 0x%16lx - 0x%16lx   (%6ld KB)\n"
		  "    PCI I/O : 0x%16lx - 0x%16lx   (%6ld MB)\n"
		  "    modules : 0x%16lx - 0x%16lx   (%6ld MB)\n"
		  "    memory  : 0x%16lx - 0x%16lx   (%6ld MB)\n"
		  "      .init : 0x%p" " - 0x%p" "   (%6ld KB)\n"
		  "      .text : 0x%p" " - 0x%p" "   (%6ld KB)\n"
		  "      .data : 0x%p" " - 0x%p" "   (%6ld KB)\n",
		  "    memory  : 0x%16lx - 0x%16lx   (%6ld MB)\n",
#ifdef CONFIG_KASAN
		  MLG(KASAN_SHADOW_START, KASAN_SHADOW_END),
#endif
		  MLM(MODULES_VADDR, MODULES_END),
		  MLG(VMALLOC_START, VMALLOC_END),
		  MLK_ROUNDUP(__init_begin, __init_end),
		  MLK_ROUNDUP(_text, _etext),
		  MLK_ROUNDUP(_sdata, _edata),
#ifdef CONFIG_SPARSEMEM_VMEMMAP
		  MLG((unsigned long)vmemmap,
		      (unsigned long)vmemmap + VMEMMAP_SIZE),
@@ -326,11 +331,7 @@ void __init mem_init(void)
#endif
		  MLK(FIXADDR_START, FIXADDR_TOP),
		  MLM(PCI_IO_START, PCI_IO_END),
		  MLM(MODULES_VADDR, MODULES_END),
		  MLM(PAGE_OFFSET, (unsigned long)high_memory),
		  MLK_ROUNDUP(__init_begin, __init_end),
		  MLK_ROUNDUP(_text, _etext),
		  MLK_ROUNDUP(_sdata, _edata));
		  MLM(PAGE_OFFSET, (unsigned long)high_memory));

#undef MLK
#undef MLM
@@ -358,8 +359,8 @@ void __init mem_init(void)

void free_initmem(void)
{
	fixup_init();
	free_initmem_default(0);
	fixup_init();
}

#ifdef CONFIG_BLK_DEV_INITRD
Loading