// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2020 SiFive
 */

#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/memory.h>
#include <linux/string.h>
#include <linux/uaccess.h>
#include <linux/stop_machine.h>
#include <asm/kprobes.h>
#include <asm/cacheflush.h>
#include <asm/fixmap.h>
#include <asm/ftrace.h>
#include <asm/patch.h>
#include <asm/sections.h>

struct patch_insn {
	void *addr;
	u32 *insns;
	int ninsns;
	atomic_t cpu_count;
};

int riscv_patch_in_stop_machine = false;

#ifdef CONFIG_MMU

static inline bool is_kernel_exittext(uintptr_t addr)
{
	return system_state < SYSTEM_RUNNING &&
		addr >= (uintptr_t)__exittext_begin &&
		addr < (uintptr_t)__exittext_end;
}

/*
 * The fix_to_virt(, idx) needs a const value (not a dynamic variable of
 * reg-a0) or BUILD_BUG_ON failed with "idx >= __end_of_fixed_addresses".
 * So use '__always_inline' and 'const unsigned int fixmap' here.
 */
static __always_inline void *patch_map(void *addr, const unsigned int fixmap)
{
	uintptr_t uintaddr = (uintptr_t) addr;
	struct page *page;

	if (core_kernel_text(uintaddr) || is_kernel_exittext(uintaddr))
		page = phys_to_page(__pa_symbol(addr));
	else if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX))
		page = vmalloc_to_page(addr);
	else
		return addr;

	BUG_ON(!page);

	return (void *)set_fixmap_offset(fixmap, page_to_phys(page) +
					 (uintaddr & ~PAGE_MASK));
}

static void patch_unmap(int fixmap)
{
	clear_fixmap(fixmap);
}
NOKPROBE_SYMBOL(patch_unmap);

static int __patch_insn_set(void *addr, u8 c, size_t len)
{
	void *waddr = addr;
	bool across_pages = (((uintptr_t)addr & ~PAGE_MASK) + len) > PAGE_SIZE;

	/*
	 * Only two pages can be mapped at a time for writing.
	 */
	if (len + offset_in_page(addr) > 2 * PAGE_SIZE)
		return -EINVAL;
	/*
	 * Before reaching here, it was expected to lock the text_mutex
	 * already, so we don't need to give another lock here and could
	 * ensure that it was safe between each cores.
	 */
	lockdep_assert_held(&text_mutex);

	preempt_disable();

	if (across_pages)
		patch_map(addr + PAGE_SIZE, FIX_TEXT_POKE1);

	waddr = patch_map(addr, FIX_TEXT_POKE0);

	memset(waddr, c, len);

	patch_unmap(FIX_TEXT_POKE0);

	if (across_pages)
		patch_unmap(FIX_TEXT_POKE1);

	preempt_enable();

	return 0;
}
NOKPROBE_SYMBOL(__patch_insn_set);

static int __patch_insn_write(void *addr, const void *insn, size_t len)
{
	void *waddr = addr;
	bool across_pages = (((uintptr_t) addr & ~PAGE_MASK) + len) > PAGE_SIZE;
	int ret;

	/*
	 * Only two pages can be mapped at a time for writing.
	 */
	if (len + offset_in_page(addr) > 2 * PAGE_SIZE)
		return -EINVAL;

	/*
	 * Before reaching here, it was expected to lock the text_mutex
	 * already, so we don't need to give another lock here and could
	 * ensure that it was safe between each cores.
	 *
	 * We're currently using stop_machine() for ftrace & kprobes, and while
	 * that ensures text_mutex is held before installing the mappings it
	 * does not ensure text_mutex is held by the calling thread.  That's
	 * safe but triggers a lockdep failure, so just elide it for that
	 * specific case.
	 */
	if (!riscv_patch_in_stop_machine)
		lockdep_assert_held(&text_mutex);

	preempt_disable();

	if (across_pages)
		patch_map(addr + PAGE_SIZE, FIX_TEXT_POKE1);

	waddr = patch_map(addr, FIX_TEXT_POKE0);

	ret = copy_to_kernel_nofault(waddr, insn, len);

	patch_unmap(FIX_TEXT_POKE0);

	if (across_pages)
		patch_unmap(FIX_TEXT_POKE1);

	preempt_enable();

	return ret;
}
NOKPROBE_SYMBOL(__patch_insn_write);
#else
static int __patch_insn_set(void *addr, u8 c, size_t len)
{
	memset(addr, c, len);

	return 0;
}
NOKPROBE_SYMBOL(__patch_insn_set);

static int __patch_insn_write(void *addr, const void *insn, size_t len)
{
	return copy_to_kernel_nofault(addr, insn, len);
}
NOKPROBE_SYMBOL(__patch_insn_write);
#endif /* CONFIG_MMU */

static int patch_insn_set(void *addr, u8 c, size_t len)
{
	size_t patched = 0;
	size_t size;
	int ret = 0;

	/*
	 * __patch_insn_set() can only work on 2 pages at a time so call it in a
	 * loop with len <= 2 * PAGE_SIZE.
	 */
	while (patched < len && !ret) {
		size = min_t(size_t, PAGE_SIZE * 2 - offset_in_page(addr + patched), len - patched);
		ret = __patch_insn_set(addr + patched, c, size);

		patched += size;
	}

	return ret;
}
NOKPROBE_SYMBOL(patch_insn_set);

int patch_text_set_nosync(void *addr, u8 c, size_t len)
{
	u32 *tp = addr;
	int ret;

	ret = patch_insn_set(tp, c, len);

	if (!ret)
		flush_icache_range((uintptr_t)tp, (uintptr_t)tp + len);

	return ret;
}
NOKPROBE_SYMBOL(patch_text_set_nosync);

static int patch_insn_write(void *addr, const void *insn, size_t len)
{
	size_t patched = 0;
	size_t size;
	int ret = 0;

	/*
	 * Copy the instructions to the destination address, two pages at a time
	 * because __patch_insn_write() can only handle len <= 2 * PAGE_SIZE.
	 */
	while (patched < len && !ret) {
		size = min_t(size_t, PAGE_SIZE * 2 - offset_in_page(addr + patched), len - patched);
		ret = __patch_insn_write(addr + patched, insn + patched, size);

		patched += size;
	}

	return ret;
}
NOKPROBE_SYMBOL(patch_insn_write);

int patch_text_nosync(void *addr, const void *insns, size_t len)
{
	u32 *tp = addr;
	int ret;

	ret = patch_insn_write(tp, insns, len);

	if (!ret)
		flush_icache_range((uintptr_t) tp, (uintptr_t) tp + len);

	return ret;
}
NOKPROBE_SYMBOL(patch_text_nosync);

static int patch_text_cb(void *data)
{
	struct patch_insn *patch = data;
	unsigned long len;
	int i, ret = 0;

	if (atomic_inc_return(&patch->cpu_count) == num_online_cpus()) {
		for (i = 0; ret == 0 && i < patch->ninsns; i++) {
			len = GET_INSN_LENGTH(patch->insns[i]);
			ret = patch_text_nosync(patch->addr + i * len,
						&patch->insns[i], len);
		}
		atomic_inc(&patch->cpu_count);
	} else {
		while (atomic_read(&patch->cpu_count) <= num_online_cpus())
			cpu_relax();
		smp_mb();
	}

	return ret;
}
NOKPROBE_SYMBOL(patch_text_cb);

int patch_text(void *addr, u32 *insns, int ninsns)
{
	int ret;
	struct patch_insn patch = {
		.addr = addr,
		.insns = insns,
		.ninsns = ninsns,
		.cpu_count = ATOMIC_INIT(0),
	};

	/*
	 * kprobes takes text_mutex, before calling patch_text(), but as we call
	 * calls stop_machine(), the lockdep assertion in patch_insn_write()
	 * gets confused by the context in which the lock is taken.
	 * Instead, ensure the lock is held before calling stop_machine(), and
	 * set riscv_patch_in_stop_machine to skip the check in
	 * patch_insn_write().
	 */
	lockdep_assert_held(&text_mutex);
	riscv_patch_in_stop_machine = true;
	ret = stop_machine_cpuslocked(patch_text_cb, &patch, cpu_online_mask);
	riscv_patch_in_stop_machine = false;
	return ret;
}
NOKPROBE_SYMBOL(patch_text);
