// SPDX-License-Identifier: GPL-2.0
#define boot_fmt(fmt) "startup: " fmt
#include <linux/string.h>
#include <linux/elf.h>
#include <asm/page-states.h>
#include <asm/boot_data.h>
#include <asm/extmem.h>
#include <asm/sections.h>
#include <asm/diag288.h>
#include <asm/maccess.h>
#include <asm/machine.h>
#include <asm/sysinfo.h>
#include <asm/cpu_mf.h>
#include <asm/setup.h>
#include <asm/timex.h>
#include <asm/kasan.h>
#include <asm/kexec.h>
#include <asm/sclp.h>
#include <asm/diag.h>
#include <asm/uv.h>
#include <asm/abs_lowcore.h>
#include <asm/physmem_info.h>
#include <asm/stacktrace.h>
#include <asm/asm-offsets.h>
#include <asm/arch-stackprotector.h>
#include "decompressor.h"
#include "boot.h"
#include "uv.h"

struct vm_layout __bootdata_preserved(vm_layout);
unsigned long __bootdata_preserved(__abs_lowcore);
unsigned long __bootdata_preserved(__memcpy_real_area);
pte_t *__bootdata_preserved(memcpy_real_ptep);
unsigned long __bootdata_preserved(VMALLOC_START);
unsigned long __bootdata_preserved(VMALLOC_END);
struct page *__bootdata_preserved(vmemmap);
unsigned long __bootdata_preserved(vmemmap_size);
unsigned long __bootdata_preserved(MODULES_VADDR);
unsigned long __bootdata_preserved(MODULES_END);
unsigned long __bootdata_preserved(max_mappable);
unsigned long __bootdata_preserved(page_noexec_mask);
unsigned long __bootdata_preserved(segment_noexec_mask);
unsigned long __bootdata_preserved(region_noexec_mask);
union tod_clock __bootdata_preserved(tod_clock_base);
u64 __bootdata_preserved(clock_comparator_max) = -1UL;

u64 __bootdata_preserved(stfle_fac_list[16]);
struct oldmem_data __bootdata_preserved(oldmem_data);

static char sysinfo_page[PAGE_SIZE] __aligned(PAGE_SIZE);

static void detect_machine_type(void)
{
	struct sysinfo_3_2_2 *vmms = (struct sysinfo_3_2_2 *)&sysinfo_page;

	/* Check current-configuration-level */
	if (stsi(NULL, 0, 0, 0) <= 2) {
		set_machine_feature(MFEATURE_LPAR);
		return;
	}
	/* Get virtual-machine cpu information. */
	if (stsi(vmms, 3, 2, 2) || !vmms->count)
		return;
	/* Detect known hypervisors */
	if (!memcmp(vmms->vm[0].cpi, "\xd2\xe5\xd4", 3))
		set_machine_feature(MFEATURE_KVM);
	else if (!memcmp(vmms->vm[0].cpi, "\xa9\x61\xe5\xd4", 4))
		set_machine_feature(MFEATURE_VM);
}

static void detect_diag288(void)
{
	/* "BEGIN" in EBCDIC character set */
	static const char cmd[] = "\xc2\xc5\xc7\xc9\xd5";
	unsigned long action, len;

	action = machine_is_vm() ? (unsigned long)cmd : LPARWDT_RESTART;
	len = machine_is_vm() ? sizeof(cmd) : 0;
	if (__diag288(WDT_FUNC_INIT, MIN_INTERVAL, action, len))
		return;
	__diag288(WDT_FUNC_CANCEL, 0, 0, 0);
	set_machine_feature(MFEATURE_DIAG288);
}

static void detect_diag9c(void)
{
	unsigned int cpu;
	int rc = 1;

	cpu = stap();
	asm_inline volatile(
		"	diag	%[cpu],%%r0,0x9c\n"
		"0:	lhi	%[rc],0\n"
		"1:\n"
		EX_TABLE(0b, 1b)
		: [rc] "+d" (rc)
		: [cpu] "d" (cpu)
		: "cc", "memory");
	if (!rc)
		set_machine_feature(MFEATURE_DIAG9C);
}

static void reset_tod_clock(void)
{
	union tod_clock clk;

	if (store_tod_clock_ext_cc(&clk) == 0)
		return;
	/* TOD clock not running. Set the clock to Unix Epoch. */
	if (set_tod_clock(TOD_UNIX_EPOCH) || store_tod_clock_ext_cc(&clk))
		disabled_wait();
	memset(&tod_clock_base, 0, sizeof(tod_clock_base));
	tod_clock_base.tod = TOD_UNIX_EPOCH;
	get_lowcore()->last_update_clock = TOD_UNIX_EPOCH;
}

static void detect_facilities(void)
{
	if (cpu_has_edat1())
		local_ctl_set_bit(0, CR0_EDAT_BIT);
	page_noexec_mask = -1UL;
	segment_noexec_mask = -1UL;
	region_noexec_mask = -1UL;
	if (!cpu_has_nx()) {
		page_noexec_mask &= ~_PAGE_NOEXEC;
		segment_noexec_mask &= ~_SEGMENT_ENTRY_NOEXEC;
		region_noexec_mask &= ~_REGION_ENTRY_NOEXEC;
	}
	if (IS_ENABLED(CONFIG_PCI) && test_facility(153))
		set_machine_feature(MFEATURE_PCI_MIO);
	reset_tod_clock();
	if (test_facility(139) && (tod_clock_base.tod >> 63)) {
		/* Enable signed clock comparator comparisons */
		set_machine_feature(MFEATURE_SCC);
		clock_comparator_max = -1UL >> 1;
		local_ctl_set_bit(0, CR0_CLOCK_COMPARATOR_SIGN_BIT);
	}
	if (test_facility(50) && test_facility(73)) {
		set_machine_feature(MFEATURE_TX);
		local_ctl_set_bit(0, CR0_TRANSACTIONAL_EXECUTION_BIT);
	}
	if (cpu_has_vx())
		local_ctl_set_bit(0, CR0_VECTOR_BIT);
}

static int cmma_test_essa(void)
{
	unsigned long tmp = 0;
	int rc = 1;

	/* Test ESSA_GET_STATE */
	asm_inline volatile(
		"	.insn	rrf,0xb9ab0000,%[tmp],%[tmp],%[cmd],0\n"
		"0:	lhi	%[rc],0\n"
		"1:\n"
		EX_TABLE(0b, 1b)
		: [rc] "+d" (rc), [tmp] "+d" (tmp)
		: [cmd] "i" (ESSA_GET_STATE)
		: "cc", "memory");
	return rc;
}

static void cmma_init(void)
{
	if (!cmma_flag)
		return;
	if (cmma_test_essa()) {
		cmma_flag = 0;
		return;
	}
	if (test_facility(147))
		cmma_flag = 2;
}

static void setup_lpp(void)
{
	get_lowcore()->current_pid = 0;
	get_lowcore()->lpp = LPP_MAGIC;
	if (test_facility(40))
		lpp(&get_lowcore()->lpp);
}

#ifdef CONFIG_KERNEL_UNCOMPRESSED
static unsigned long mem_safe_offset(void)
{
	return (unsigned long)_compressed_start;
}

static void deploy_kernel(void *output)
{
	void *uncompressed_start = (void *)_compressed_start;

	if (output == uncompressed_start)
		return;
	memmove(output, uncompressed_start, vmlinux.image_size);
	memset(uncompressed_start, 0, vmlinux.image_size);
}
#endif

static void rescue_initrd(unsigned long min, unsigned long max)
{
	unsigned long old_addr, addr, size;

	if (!IS_ENABLED(CONFIG_BLK_DEV_INITRD))
		return;
	if (!get_physmem_reserved(RR_INITRD, &addr, &size))
		return;
	if (addr >= min && addr + size <= max)
		return;
	old_addr = addr;
	physmem_free(RR_INITRD);
	addr = physmem_alloc_or_die(RR_INITRD, size, 0);
	memmove((void *)addr, (void *)old_addr, size);
}

static void copy_bootdata(void)
{
	if (__boot_data_end - __boot_data_start != vmlinux.bootdata_size)
		boot_panic(".boot.data section size mismatch\n");
	memcpy((void *)vmlinux.bootdata_off, __boot_data_start, vmlinux.bootdata_size);
	if (__boot_data_preserved_end - __boot_data_preserved_start != vmlinux.bootdata_preserved_size)
		boot_panic(".boot.preserved.data section size mismatch\n");
	memcpy((void *)vmlinux.bootdata_preserved_off, __boot_data_preserved_start, vmlinux.bootdata_preserved_size);
}

static void kaslr_adjust_relocs(unsigned long min_addr, unsigned long max_addr,
				unsigned long offset, unsigned long phys_offset)
{
	int *reloc;
	long loc;

	/* Adjust R_390_64 relocations */
	for (reloc = (int *)__vmlinux_relocs_64_start; reloc < (int *)__vmlinux_relocs_64_end; reloc++) {
		loc = (long)*reloc + phys_offset;
		if (loc < min_addr || loc > max_addr)
			boot_panic("64-bit relocation outside of kernel!\n");
		*(u64 *)loc += offset;
	}
}

static void kaslr_adjust_got(unsigned long offset)
{
	u64 *entry;

	/*
	 * Adjust GOT entries, except for ones for undefined weak symbols
	 * that resolved to zero. This also skips the first three reserved
	 * entries on s390x that are zero.
	 */
	for (entry = (u64 *)vmlinux.got_start; entry < (u64 *)vmlinux.got_end; entry++) {
		if (*entry)
			*entry += offset;
	}
}

/*
 * Merge information from several sources into a single ident_map_size value.
 * "ident_map_size" represents the upper limit of physical memory we may ever
 * reach. It might not be all online memory, but also include standby (offline)
 * memory or memory areas reserved for other means (e.g., memory devices such as
 * virtio-mem).
 *
 * "ident_map_size" could be lower then actual standby/reserved or even online
 * memory present, due to limiting factors. We should never go above this limit.
 * It is the size of our identity mapping.
 *
 * Consider the following factors:
 * 1. max_physmem_end - end of physical memory online, standby or reserved.
 *    Always >= end of the last online memory range (get_physmem_online_end()).
 * 2. CONFIG_MAX_PHYSMEM_BITS - the maximum size of physical memory the
 *    kernel is able to support.
 * 3. "mem=" kernel command line option which limits physical memory usage.
 * 4. OLDMEM_BASE which is a kdump memory limit when the kernel is executed as
 *    crash kernel.
 * 5. "hsa" size which is a memory limit when the kernel is executed during
 *    zfcp/nvme dump.
 */
static void setup_ident_map_size(unsigned long max_physmem_end)
{
	unsigned long hsa_size;

	ident_map_size = max_physmem_end;
	if (memory_limit)
		ident_map_size = min(ident_map_size, memory_limit);
	ident_map_size = min(ident_map_size, 1UL << MAX_PHYSMEM_BITS);

#ifdef CONFIG_CRASH_DUMP
	if (oldmem_data.start) {
		__kaslr_enabled = 0;
		ident_map_size = min(ident_map_size, oldmem_data.size);
		boot_debug("kdump memory limit:  0x%016lx\n", oldmem_data.size);
	} else if (ipl_block_valid && is_ipl_block_dump()) {
		__kaslr_enabled = 0;
		if (!sclp_early_get_hsa_size(&hsa_size) && hsa_size) {
			ident_map_size = min(ident_map_size, hsa_size);
			boot_debug("Stand-alone dump limit: 0x%016lx\n", hsa_size);
		}
	}
#endif
	boot_debug("Identity map size:   0x%016lx\n", ident_map_size);
}

#define FIXMAP_SIZE	round_up(MEMCPY_REAL_SIZE + ABS_LOWCORE_MAP_SIZE, sizeof(struct lowcore))

static unsigned long get_vmem_size(unsigned long identity_size,
				   unsigned long vmemmap_size,
				   unsigned long vmalloc_size,
				   unsigned long rte_size)
{
	unsigned long max_mappable, vsize;

	max_mappable = max(identity_size, MAX_DCSS_ADDR);
	vsize = round_up(SZ_2G + max_mappable, rte_size) +
		round_up(vmemmap_size, rte_size) +
		FIXMAP_SIZE + MODULES_LEN + KASLR_LEN;
	if (IS_ENABLED(CONFIG_KMSAN))
		vsize += MODULES_LEN * 2;
	return size_add(vsize, vmalloc_size);
}

static unsigned long setup_kernel_memory_layout(unsigned long kernel_size)
{
	unsigned long vmemmap_start;
	unsigned long kernel_start;
	unsigned long asce_limit;
	unsigned long rte_size;
	unsigned long pages;
	unsigned long vsize;
	unsigned long vmax;

	pages = ident_map_size / PAGE_SIZE;
	/* vmemmap contains a multiple of PAGES_PER_SECTION struct pages */
	vmemmap_size = SECTION_ALIGN_UP(pages) * sizeof(struct page);

	/* choose kernel address space layout: 4 or 3 levels. */
	BUILD_BUG_ON(!IS_ALIGNED(TEXT_OFFSET, THREAD_SIZE));
	BUILD_BUG_ON(!IS_ALIGNED(__NO_KASLR_START_KERNEL, THREAD_SIZE));
	BUILD_BUG_ON(__NO_KASLR_END_KERNEL > _REGION1_SIZE);
	BUILD_BUG_ON(CONFIG_ILLEGAL_POINTER_VALUE < _REGION1_SIZE);
	vsize = get_vmem_size(ident_map_size, vmemmap_size, vmalloc_size, _REGION3_SIZE);
	boot_debug("vmem size estimated: 0x%016lx\n", vsize);
	if (IS_ENABLED(CONFIG_KASAN) || __NO_KASLR_END_KERNEL > _REGION2_SIZE ||
	    (vsize > _REGION2_SIZE && kaslr_enabled())) {
		asce_limit = _REGION1_SIZE;
		if (__NO_KASLR_END_KERNEL > _REGION2_SIZE) {
			rte_size = _REGION2_SIZE;
			vsize = get_vmem_size(ident_map_size, vmemmap_size, vmalloc_size, _REGION2_SIZE);
		} else {
			rte_size = _REGION3_SIZE;
		}
	} else {
		asce_limit = _REGION2_SIZE;
		rte_size = _REGION3_SIZE;
	}

	/*
	 * Forcing modules and vmalloc area under the ultravisor
	 * secure storage limit, so that any vmalloc allocation
	 * we do could be used to back secure guest storage.
	 *
	 * Assume the secure storage limit always exceeds _REGION2_SIZE,
	 * otherwise asce_limit and rte_size would have been adjusted.
	 */
	vmax = adjust_to_uv_max(asce_limit);
	boot_debug("%d level paging       0x%016lx vmax\n", vmax == _REGION1_SIZE ? 4 : 3, vmax);
#ifdef CONFIG_KASAN
	BUILD_BUG_ON(__NO_KASLR_END_KERNEL > KASAN_SHADOW_START);
	boot_debug("KASAN shadow area:   0x%016lx-0x%016lx\n", KASAN_SHADOW_START, KASAN_SHADOW_END);
	/* force vmalloc and modules below kasan shadow */
	vmax = min(vmax, KASAN_SHADOW_START);
#endif
	vsize = min(vsize, vmax);
	if (kaslr_enabled()) {
		unsigned long kernel_end, kaslr_len, slots, pos;

		kaslr_len = max(KASLR_LEN, vmax - vsize);
		slots = DIV_ROUND_UP(kaslr_len - kernel_size, THREAD_SIZE);
		if (get_random(slots, &pos))
			pos = 0;
		kernel_end = vmax - pos * THREAD_SIZE;
		kernel_start = round_down(kernel_end - kernel_size, THREAD_SIZE);
		boot_debug("Randomization range: 0x%016lx-0x%016lx\n", vmax - kaslr_len, vmax);
		boot_debug("kernel image:        0x%016lx-0x%016lx (kaslr)\n", kernel_start,
			   kernel_start + kernel_size);
	} else if (vmax < __NO_KASLR_END_KERNEL || vsize > __NO_KASLR_END_KERNEL) {
		kernel_start = round_down(vmax - kernel_size, THREAD_SIZE);
		boot_debug("kernel image:        0x%016lx-0x%016lx (constrained)\n", kernel_start,
			   kernel_start + kernel_size);
	} else {
		kernel_start = __NO_KASLR_START_KERNEL;
		boot_debug("kernel image:        0x%016lx-0x%016lx (nokaslr)\n", kernel_start,
			   kernel_start + kernel_size);
	}
	__kaslr_offset = kernel_start;
	boot_debug("__kaslr_offset:      0x%016lx\n", __kaslr_offset);

	MODULES_END = round_down(kernel_start, _SEGMENT_SIZE);
	MODULES_VADDR = MODULES_END - MODULES_LEN;
	VMALLOC_END = MODULES_VADDR;
	if (IS_ENABLED(CONFIG_KMSAN))
		VMALLOC_END -= MODULES_LEN * 2;
	boot_debug("modules area:        0x%016lx-0x%016lx\n", MODULES_VADDR, MODULES_END);

	/* allow vmalloc area to occupy up to about 1/2 of the rest virtual space left */
	vsize = (VMALLOC_END - FIXMAP_SIZE) / 2;
	vsize = round_down(vsize, _SEGMENT_SIZE);
	vmalloc_size = min(vmalloc_size, vsize);
	if (IS_ENABLED(CONFIG_KMSAN)) {
		/* take 2/3 of vmalloc area for KMSAN shadow and origins */
		vmalloc_size = round_down(vmalloc_size / 3, _SEGMENT_SIZE);
		VMALLOC_END -= vmalloc_size * 2;
	}
	VMALLOC_START = VMALLOC_END - vmalloc_size;
	boot_debug("vmalloc area:        0x%016lx-0x%016lx\n", VMALLOC_START, VMALLOC_END);

	__memcpy_real_area = round_down(VMALLOC_START - MEMCPY_REAL_SIZE, PAGE_SIZE);
	boot_debug("memcpy real area:    0x%016lx-0x%016lx\n", __memcpy_real_area,
		   __memcpy_real_area + MEMCPY_REAL_SIZE);
	__abs_lowcore = round_down(__memcpy_real_area - ABS_LOWCORE_MAP_SIZE,
				   sizeof(struct lowcore));
	boot_debug("abs lowcore:         0x%016lx-0x%016lx\n", __abs_lowcore,
		   __abs_lowcore + ABS_LOWCORE_MAP_SIZE);

	/* split remaining virtual space between 1:1 mapping & vmemmap array */
	pages = __abs_lowcore / (PAGE_SIZE + sizeof(struct page));
	pages = SECTION_ALIGN_UP(pages);
	/* keep vmemmap_start aligned to a top level region table entry */
	vmemmap_start = round_down(__abs_lowcore - pages * sizeof(struct page), rte_size);
	/* make sure identity map doesn't overlay with vmemmap */
	ident_map_size = min(ident_map_size, vmemmap_start);
	vmemmap_size = SECTION_ALIGN_UP(ident_map_size / PAGE_SIZE) * sizeof(struct page);
	/* make sure vmemmap doesn't overlay with absolute lowcore area */
	if (vmemmap_start + vmemmap_size > __abs_lowcore) {
		vmemmap_size = SECTION_ALIGN_DOWN(ident_map_size / PAGE_SIZE) * sizeof(struct page);
		ident_map_size = vmemmap_size / sizeof(struct page) * PAGE_SIZE;
	}
	vmemmap = (struct page *)vmemmap_start;
	/* maximum address for which linear mapping could be created (DCSS, memory) */
	BUILD_BUG_ON(MAX_DCSS_ADDR > (1UL << MAX_PHYSMEM_BITS));
	max_mappable = max(ident_map_size, MAX_DCSS_ADDR);
	max_mappable = min(max_mappable, vmemmap_start);
#ifdef CONFIG_RANDOMIZE_IDENTITY_BASE
	if (kaslr_enabled())
		__identity_base = round_down(vmemmap_start - max_mappable, rte_size);
#endif
	boot_debug("identity map:        0x%016lx-0x%016lx\n", __identity_base,
		   __identity_base + ident_map_size);

	return asce_limit;
}

/*
 * This function clears the BSS section of the decompressed Linux kernel and NOT the decompressor's.
 */
static void clear_bss_section(unsigned long kernel_start)
{
	memset((void *)kernel_start + vmlinux.image_size, 0, vmlinux.bss_size);
}

/*
 * Set vmalloc area size to an 8th of (potential) physical memory
 * size, unless size has been set by kernel command line parameter.
 */
static void setup_vmalloc_size(void)
{
	unsigned long size;

	if (vmalloc_size_set)
		return;
	size = round_up(ident_map_size / 8, _SEGMENT_SIZE);
	vmalloc_size = max(size, vmalloc_size);
}

static void kaslr_adjust_vmlinux_info(long offset)
{
	vmlinux.bootdata_off += offset;
	vmlinux.bootdata_preserved_off += offset;
	vmlinux.got_start += offset;
	vmlinux.got_end += offset;
	vmlinux.init_mm_off += offset;
	vmlinux.swapper_pg_dir_off += offset;
	vmlinux.invalid_pg_dir_off += offset;
	vmlinux.alt_instructions += offset;
	vmlinux.alt_instructions_end += offset;
#ifdef CONFIG_STACKPROTECTOR
	vmlinux.stack_prot_start += offset;
	vmlinux.stack_prot_end += offset;
#endif
#ifdef CONFIG_KASAN
	vmlinux.kasan_early_shadow_page_off += offset;
	vmlinux.kasan_early_shadow_pte_off += offset;
	vmlinux.kasan_early_shadow_pmd_off += offset;
	vmlinux.kasan_early_shadow_pud_off += offset;
	vmlinux.kasan_early_shadow_p4d_off += offset;
#endif
}

void startup_kernel(void)
{
	unsigned long vmlinux_size = vmlinux.image_size + vmlinux.bss_size;
	unsigned long nokaslr_text_lma, text_lma = 0, amode31_lma = 0;
	unsigned long kernel_size = TEXT_OFFSET + vmlinux_size;
	unsigned long kaslr_large_page_offset;
	unsigned long max_physmem_end;
	unsigned long asce_limit;
	unsigned long safe_addr;
	psw_t psw;

	setup_lpp();
	store_ipl_parmblock();
	uv_query_info();
	setup_boot_command_line();
	parse_boot_command_line();

	/*
	 * Non-randomized kernel physical start address must be _SEGMENT_SIZE
	 * aligned (see blow).
	 */
	nokaslr_text_lma = ALIGN(mem_safe_offset(), _SEGMENT_SIZE);
	safe_addr = PAGE_ALIGN(nokaslr_text_lma + vmlinux_size);

	/*
	 * Reserve decompressor memory together with decompression heap,
	 * buffer and memory which might be occupied by uncompressed kernel
	 * (if KASLR is off or failed).
	 */
	physmem_reserve(RR_DECOMPRESSOR, 0, safe_addr);
	if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && parmarea.initrd_size)
		physmem_reserve(RR_INITRD, parmarea.initrd_start, parmarea.initrd_size);
	oldmem_data.start = parmarea.oldmem_base;
	oldmem_data.size = parmarea.oldmem_size;

	read_ipl_report();
	sclp_early_read_info();
	sclp_early_detect_machine_features();
	detect_facilities();
	detect_diag9c();
	detect_machine_type();
	/* detect_diag288() needs machine type */
	detect_diag288();
	cmma_init();
	sanitize_prot_virt_host();
	max_physmem_end = detect_max_physmem_end();
	setup_ident_map_size(max_physmem_end);
	setup_vmalloc_size();
	asce_limit = setup_kernel_memory_layout(kernel_size);
	/* got final ident_map_size, physmem allocations could be performed now */
	physmem_set_usable_limit(ident_map_size);
	detect_physmem_online_ranges(max_physmem_end);
	save_ipl_cert_comp_list();
	rescue_initrd(safe_addr, ident_map_size);

	/*
	 * __kaslr_offset_phys must be _SEGMENT_SIZE aligned, so the lower
	 * 20 bits (the offset within a large page) are zero. Copy the last
	 * 20 bits of __kaslr_offset, which is THREAD_SIZE aligned, to
	 * __kaslr_offset_phys.
	 *
	 * With this the last 20 bits of __kaslr_offset_phys and __kaslr_offset
	 * are identical, which is required to allow for large mappings of the
	 * kernel image.
	 */
	kaslr_large_page_offset = __kaslr_offset & ~_SEGMENT_MASK;
	if (kaslr_enabled()) {
		unsigned long size = vmlinux_size + kaslr_large_page_offset;

		text_lma = randomize_within_range(size, _SEGMENT_SIZE, TEXT_OFFSET, ident_map_size);
	}
	if (!text_lma)
		text_lma = nokaslr_text_lma;
	text_lma |= kaslr_large_page_offset;

	/*
	 * [__kaslr_offset_phys..__kaslr_offset_phys + TEXT_OFFSET] region is
	 * never accessed via the kernel image mapping as per the linker script:
	 *
	 *	. = TEXT_OFFSET;
	 *
	 * Therefore, this region could be used for something else and does
	 * not need to be reserved. See how it is skipped in setup_vmem().
	 */
	__kaslr_offset_phys = text_lma - TEXT_OFFSET;
	kaslr_adjust_vmlinux_info(__kaslr_offset_phys);
	physmem_reserve(RR_VMLINUX, text_lma, vmlinux_size);
	deploy_kernel((void *)text_lma);

	/* vmlinux decompression is done, shrink reserved low memory */
	physmem_reserve(RR_DECOMPRESSOR, 0, (unsigned long)_decompressor_end);

	/*
	 * In case KASLR is enabled the randomized location of .amode31
	 * section might overlap with .vmlinux.relocs section. To avoid that
	 * the below randomize_within_range() could have been called with
	 * __vmlinux_relocs_64_end as the lower range address. However,
	 * .amode31 section is written to by the decompressed kernel - at
	 * that time the contents of .vmlinux.relocs is not needed anymore.
	 * Conversely, .vmlinux.relocs is read only by the decompressor, even
	 * before the kernel started. Therefore, in case the two sections
	 * overlap there is no risk of corrupting any data.
	 */
	if (kaslr_enabled()) {
		unsigned long amode31_min;

		amode31_min = (unsigned long)_decompressor_end;
		amode31_lma = randomize_within_range(vmlinux.amode31_size, PAGE_SIZE, amode31_min, SZ_2G);
	}
	if (!amode31_lma)
		amode31_lma = text_lma - vmlinux.amode31_size;
	physmem_reserve(RR_AMODE31, amode31_lma, vmlinux.amode31_size);

	/*
	 * The order of the following operations is important:
	 *
	 * - kaslr_adjust_relocs() must follow clear_bss_section() to establish
	 *   static memory references to data in .bss to be used by setup_vmem()
	 *   (i.e init_mm.pgd)
	 *
	 * - setup_vmem() must follow kaslr_adjust_relocs() to be able using
	 *   static memory references to data in .bss (i.e init_mm.pgd)
	 *
	 * - copy_bootdata() must follow setup_vmem() to propagate changes
	 *   to bootdata made by setup_vmem()
	 */
	clear_bss_section(text_lma);
	kaslr_adjust_relocs(text_lma, text_lma + vmlinux.image_size,
			    __kaslr_offset, __kaslr_offset_phys);
	kaslr_adjust_got(__kaslr_offset);
	setup_vmem(__kaslr_offset, __kaslr_offset + kernel_size, asce_limit);
	dump_physmem_reserved();
	copy_bootdata();
	__apply_alternatives((struct alt_instr *)_vmlinux_info.alt_instructions,
			     (struct alt_instr *)_vmlinux_info.alt_instructions_end,
			     ALT_CTX_EARLY);
	stack_protector_apply_early(text_lma);

	/*
	 * Save KASLR offset for early dumps, before vmcore_info is set.
	 * Mark as uneven to distinguish from real vmcore_info pointer.
	 */
	get_lowcore()->vmcore_info = __kaslr_offset_phys ? __kaslr_offset_phys | 0x1UL : 0;

	/*
	 * Jump to the decompressed kernel entry point and switch DAT mode on.
	 */
	psw.addr = __kaslr_offset + vmlinux.entry;
	psw.mask = PSW_KERNEL_BITS;
	boot_debug("Starting kernel at:  0x%016lx\n", psw.addr);
	jump_to_kernel(&psw);
}
