/*
 * 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 void __init apply_r_mips_64_rel(u32 *loc_new, long offset)
{
	*(u64 *)loc_new += offset;
}

static void __init apply_r_mips_32_rel(u32 *loc_new, long offset)
{
	*loc_new += offset;
}

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 void __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);
}

static int __init reloc_handler(u32 type, u32 *loc_orig, u32 *loc_new,
				long offset)
{
	switch (type) {
	case R_MIPS_64:
		apply_r_mips_64_rel(loc_new, offset);
		break;
	case R_MIPS_32:
		apply_r_mips_32_rel(loc_new, offset);
		break;
	case R_MIPS_26:
		return apply_r_mips_26_rel(loc_orig, loc_new, offset);
	case R_MIPS_HI16:
		apply_r_mips_hi16_rel(loc_orig, loc_new, offset);
		break;
	default:
		pr_err("Unhandled relocation type %d at 0x%pK\n", type,
		       loc_orig);
		return -ENOEXEC;
	}

	return 0;
}

static 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);

		res = reloc_handler(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;
}

static inline void __init update_kaslr_offset(unsigned long *addr, long offset)
{
	unsigned long *new_addr = (unsigned long *)RELOCATED(addr);

	*new_addr = (unsigned long)offset;
}

#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);

		/* Error may occur before, so keep it at last */
		update_kaslr_offset(&__kaslr_offset, offset);
	}
out:
	return kernel_entry;
}

/*
 * Show relocation information on panic.
 */
static void show_kernel_relocation(const char *level)
{
	if (__kaslr_offset > 0) {
		printk(level);
		pr_cont("Kernel relocated by 0x%pK\n", (void *)__kaslr_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);
