/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Support for Kernel relocation at boot time
 *
 * Copyright (C) 2015, Imagination Technologies Ltd.
 * Authors: Matt Redfearn (matt.redfearn@mips.com)
 */
#include <asm/bootinfo.h>
#include <asm/cacheflush.h>
#include <asm/fw/fw.h>
#include <asm/sections.h>
#include <asm/setup.h>
#include <asm/timex.h>
#include <linux/elf.h>
#include <linux/kernel.h>
#include <linux/libfdt.h>
#include <linux/of_fdt.h>
#include <linux/sched/task.h>
#include <linux/start_kernel.h>
#include <linux/string.h>
#include <linux/printk.h>

#define RELOCATED(x) ((void *)((long)x + offset))

extern u32 _relocation_start[];	/* End kernel image / start relocation table */
extern u32 _relocation_end[];	/* End relocation table */

extern long __start___ex_table;	/* Start exception table */
extern long __stop___ex_table;	/* End exception table */

extern void __weak plat_fdt_relocated(void *new_location);

/*
 * This function may be defined for a platform to perform any post-relocation
 * fixup necessary.
 * Return non-zero to abort relocation
 */
int __weak plat_post_relocation(long offset)
{
	return 0;
}

static inline u32 __init get_synci_step(void)
{
	u32 res;

	__asm__("rdhwr  %0, $1" : "=r" (res));

	return res;
}

static void __init sync_icache(void *kbase, unsigned long kernel_length)
{
	void *kend = kbase + kernel_length;
	u32 step = get_synci_step();

	do {
		__asm__ __volatile__(
			"synci  0(%0)"
			: /* no output */
			: "r" (kbase));

		kbase += step;
	} while (step && kbase < kend);

	/* Completion barrier */
	__sync();
}

static int __init apply_r_mips_64_rel(u32 *loc_orig, u32 *loc_new, long offset)
{
	*(u64 *)loc_new += offset;

	return 0;
}

static int __init apply_r_mips_32_rel(u32 *loc_orig, u32 *loc_new, long offset)
{
	*loc_new += offset;

	return 0;
}

static int __init apply_r_mips_26_rel(u32 *loc_orig, u32 *loc_new, long offset)
{
	unsigned long target_addr = (*loc_orig) & 0x03ffffff;

	if (offset % 4) {
		pr_err("Dangerous R_MIPS_26 REL relocation\n");
		return -ENOEXEC;
	}

	/* Original target address */
	target_addr <<= 2;
	target_addr += (unsigned long)loc_orig & 0xf0000000;

	/* Get the new target address */
	target_addr += offset;

	if ((target_addr & 0xf0000000) != ((unsigned long)loc_new & 0xf0000000)) {
		pr_err("R_MIPS_26 REL relocation overflow\n");
		return -ENOEXEC;
	}

	target_addr -= (unsigned long)loc_new & 0xf0000000;
	target_addr >>= 2;

	*loc_new = (*loc_new & ~0x03ffffff) | (target_addr & 0x03ffffff);

	return 0;
}


static int __init apply_r_mips_hi16_rel(u32 *loc_orig, u32 *loc_new, long offset)
{
	unsigned long insn = *loc_orig;
	unsigned long target = (insn & 0xffff) << 16; /* high 16bits of target */

	target += offset;

	*loc_new = (insn & ~0xffff) | ((target >> 16) & 0xffff);
	return 0;
}

static int (*reloc_handlers_rel[]) (u32 *, u32 *, long) __initdata = {
	[R_MIPS_64]		= apply_r_mips_64_rel,
	[R_MIPS_32]		= apply_r_mips_32_rel,
	[R_MIPS_26]		= apply_r_mips_26_rel,
	[R_MIPS_HI16]		= apply_r_mips_hi16_rel,
};

int __init do_relocations(void *kbase_old, void *kbase_new, long offset)
{
	u32 *r;
	u32 *loc_orig;
	u32 *loc_new;
	int type;
	int res;

	for (r = _relocation_start; r < _relocation_end; r++) {
		/* Sentinel for last relocation */
		if (*r == 0)
			break;

		type = (*r >> 24) & 0xff;
		loc_orig = kbase_old + ((*r & 0x00ffffff) << 2);
		loc_new = RELOCATED(loc_orig);

		if (reloc_handlers_rel[type] == NULL) {
			/* Unsupported relocation */
			pr_err("Unhandled relocation type %d at 0x%pK\n",
			       type, loc_orig);
			return -ENOEXEC;
		}

		res = reloc_handlers_rel[type](loc_orig, loc_new, offset);
		if (res)
			return res;
	}

	return 0;
}

/*
 * The exception table is filled in by the relocs tool after vmlinux is linked.
 * It must be relocated separately since there will not be any relocation
 * information for it filled in by the linker.
 */
static int __init relocate_exception_table(long offset)
{
	unsigned long *etable_start, *etable_end, *e;

	etable_start = RELOCATED(&__start___ex_table);
	etable_end = RELOCATED(&__stop___ex_table);

	for (e = etable_start; e < etable_end; e++)
		*e += offset;

	return 0;
}

#ifdef CONFIG_RANDOMIZE_BASE

static inline __init unsigned long rotate_xor(unsigned long hash,
					      const void *area, size_t size)
{
	const typeof(hash) *ptr = PTR_ALIGN(area, sizeof(hash));
	size_t diff, i;

	diff = (void *)ptr - area;
	if (unlikely(size < diff + sizeof(hash)))
		return hash;

	size = ALIGN_DOWN(size - diff, sizeof(hash));

	for (i = 0; i < size / sizeof(hash); i++) {
		/* Rotate by odd number of bits and XOR. */
		hash = (hash << ((sizeof(hash) * 8) - 7)) | (hash >> 7);
		hash ^= ptr[i];
	}

	return hash;
}

static inline __init unsigned long get_random_boot(void)
{
	unsigned long entropy = random_get_entropy();
	unsigned long hash = 0;

	/* Attempt to create a simple but unpredictable starting entropy. */
	hash = rotate_xor(hash, linux_banner, strlen(linux_banner));

	/* Add in any runtime entropy we can get */
	hash = rotate_xor(hash, &entropy, sizeof(entropy));

#if defined(CONFIG_USE_OF)
	/* Get any additional entropy passed in device tree */
	if (initial_boot_params) {
		int node, len;
		u64 *prop;

		node = fdt_path_offset(initial_boot_params, "/chosen");
		if (node >= 0) {
			prop = fdt_getprop_w(initial_boot_params, node,
					     "kaslr-seed", &len);
			if (prop && (len == sizeof(u64)))
				hash = rotate_xor(hash, prop, sizeof(*prop));
		}
	}
#endif /* CONFIG_USE_OF */

	return hash;
}

static inline __init bool kaslr_disabled(void)
{
	char *str;

#if defined(CONFIG_CMDLINE_BOOL)
	const char *builtin_cmdline = CONFIG_CMDLINE;

	str = strstr(builtin_cmdline, "nokaslr");
	if (str == builtin_cmdline ||
	    (str > builtin_cmdline && *(str - 1) == ' '))
		return true;
#endif
	str = strstr(arcs_cmdline, "nokaslr");
	if (str == arcs_cmdline || (str > arcs_cmdline && *(str - 1) == ' '))
		return true;

	return false;
}

static inline void __init *determine_relocation_address(void)
{
	/* Choose a new address for the kernel */
	unsigned long kernel_length;
	void *dest = &_text;
	unsigned long offset;

	if (kaslr_disabled())
		return dest;

	kernel_length = (long)_end - (long)(&_text);

	offset = get_random_boot() << 16;
	offset &= (CONFIG_RANDOMIZE_BASE_MAX_OFFSET - 1);
	if (offset < kernel_length)
		offset += ALIGN(kernel_length, 0xffff);

	return RELOCATED(dest);
}

#else

static inline void __init *determine_relocation_address(void)
{
	/*
	 * Choose a new address for the kernel
	 * For now we'll hard code the destination
	 */
	return (void *)0xffffffff81000000;
}

#endif

static inline int __init relocation_addr_valid(void *loc_new)
{
	if ((unsigned long)loc_new & 0x0000ffff) {
		/* Inappropriately aligned new location */
		return 0;
	}
	if ((unsigned long)loc_new < (unsigned long)&_end) {
		/* New location overlaps original kernel */
		return 0;
	}
	return 1;
}

#if defined(CONFIG_USE_OF)
void __weak *plat_get_fdt(void)
{
	return NULL;
}
#endif

void *__init relocate_kernel(void)
{
	void *loc_new;
	unsigned long kernel_length;
	unsigned long bss_length;
	long offset = 0;
	int res = 1;
	/* Default to original kernel entry point */
	void *kernel_entry = start_kernel;
	void *fdt = NULL;

	/* Get the command line */
	fw_init_cmdline();
#if defined(CONFIG_USE_OF)
	/* Deal with the device tree */
	fdt = plat_get_fdt();
	early_init_dt_scan(fdt);
	if (boot_command_line[0]) {
		/* Boot command line was passed in device tree */
		strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
	}
#endif /* CONFIG_USE_OF */

	kernel_length = (long)(&_relocation_start) - (long)(&_text);
	bss_length = (long)&__bss_stop - (long)&__bss_start;

	loc_new = determine_relocation_address();

	/* Sanity check relocation address */
	if (relocation_addr_valid(loc_new))
		offset = (unsigned long)loc_new - (unsigned long)(&_text);

	/* Reset the command line now so we don't end up with a duplicate */
	arcs_cmdline[0] = '\0';

	if (offset) {
		void (*fdt_relocated_)(void *) = NULL;
#if defined(CONFIG_USE_OF)
		unsigned long fdt_phys = virt_to_phys(fdt);

		/*
		 * If built-in dtb is used then it will have been relocated
		 * during kernel _text relocation. If appended DTB is used
		 * then it will not be relocated, but it should remain
		 * intact in the original location. If dtb is loaded by
		 * the bootloader then it may need to be moved if it crosses
		 * the target memory area
		 */

		if (fdt_phys >= virt_to_phys(RELOCATED(&_text)) &&
			fdt_phys <= virt_to_phys(RELOCATED(&_end))) {
			void *fdt_relocated =
				RELOCATED(ALIGN((long)&_end, PAGE_SIZE));
			memcpy(fdt_relocated, fdt, fdt_totalsize(fdt));
			fdt = fdt_relocated;
			fdt_relocated_ = RELOCATED(&plat_fdt_relocated);
		}
#endif /* CONFIG_USE_OF */

		/* Copy the kernel to it's new location */
		memcpy(loc_new, &_text, kernel_length);

		/* Perform relocations on the new kernel */
		res = do_relocations(&_text, loc_new, offset);
		if (res < 0)
			goto out;

		/* Sync the caches ready for execution of new kernel */
		sync_icache(loc_new, kernel_length);

		res = relocate_exception_table(offset);
		if (res < 0)
			goto out;

		/*
		 * The original .bss has already been cleared, and
		 * some variables such as command line parameters
		 * stored to it so make a copy in the new location.
		 */
		memcpy(RELOCATED(&__bss_start), &__bss_start, bss_length);

		/*
		 * If fdt was stored outside of the kernel image and
		 * had to be moved then update platform's state data
		 * with the new fdt location
		 */
		if (fdt_relocated_)
			fdt_relocated_(fdt);

		/*
		 * Last chance for the platform to abort relocation.
		 * This may also be used by the platform to perform any
		 * initialisation required now that the new kernel is
		 * resident in memory and ready to be executed.
		 */
		if (plat_post_relocation(offset))
			goto out;

		/* The current thread is now within the relocated image */
		__current_thread_info = RELOCATED(&init_thread_union);

		/* Return the new kernel's entry point */
		kernel_entry = RELOCATED(start_kernel);
	}
out:
	return kernel_entry;
}

/*
 * Show relocation information on panic.
 */
void show_kernel_relocation(const char *level)
{
	unsigned long offset;

	offset = __pa_symbol(_text) - __pa_symbol(VMLINUX_LOAD_ADDRESS);

	if (IS_ENABLED(CONFIG_RELOCATABLE) && offset > 0) {
		printk(level);
		pr_cont("Kernel relocated by 0x%pK\n", (void *)offset);
		pr_cont(" .text @ 0x%pK\n", _text);
		pr_cont(" .data @ 0x%pK\n", _sdata);
		pr_cont(" .bss  @ 0x%pK\n", __bss_start);
	}
}

static int kernel_location_notifier_fn(struct notifier_block *self,
				       unsigned long v, void *p)
{
	show_kernel_relocation(KERN_EMERG);
	return NOTIFY_DONE;
}

static struct notifier_block kernel_location_notifier = {
	.notifier_call = kernel_location_notifier_fn
};

static int __init register_kernel_offset_dumper(void)
{
	atomic_notifier_chain_register(&panic_notifier_list,
				       &kernel_location_notifier);
	return 0;
}
__initcall(register_kernel_offset_dumper);
