// SPDX-License-Identifier: GPL-2.0
#include <asm/insn.h>

#include "perf_event.h"

static int decode_branch_type(struct insn *insn)
{
	int ext;

	if (insn_get_opcode(insn))
		return X86_BR_ABORT;

	switch (insn->opcode.bytes[0]) {
	case 0xf:
		switch (insn->opcode.bytes[1]) {
		case 0x05: /* syscall */
		case 0x34: /* sysenter */
			return X86_BR_SYSCALL;
		case 0x07: /* sysret */
		case 0x35: /* sysexit */
			return X86_BR_SYSRET;
		case 0x80 ... 0x8f: /* conditional */
			return X86_BR_JCC;
		}
		return X86_BR_NONE;
	case 0x70 ... 0x7f: /* conditional */
		return X86_BR_JCC;
	case 0xc2: /* near ret */
	case 0xc3: /* near ret */
	case 0xca: /* far ret */
	case 0xcb: /* far ret */
		return X86_BR_RET;
	case 0xcf: /* iret */
		return X86_BR_IRET;
	case 0xcc ... 0xce: /* int */
		return X86_BR_INT;
	case 0xe8: /* call near rel */
		if (insn_get_immediate(insn) || insn->immediate1.value == 0) {
			/* zero length call */
			return X86_BR_ZERO_CALL;
		}
		fallthrough;
	case 0x9a: /* call far absolute */
		return X86_BR_CALL;
	case 0xe0 ... 0xe3: /* loop jmp */
		return X86_BR_JCC;
	case 0xe9 ... 0xeb: /* jmp */
		return X86_BR_JMP;
	case 0xff: /* call near absolute, call far absolute ind */
		if (insn_get_modrm(insn))
			return X86_BR_ABORT;

		ext = (insn->modrm.bytes[0] >> 3) & 0x7;
		switch (ext) {
		case 2: /* near ind call */
		case 3: /* far ind call */
			return X86_BR_IND_CALL;
		case 4:
		case 5:
			return X86_BR_IND_JMP;
		}
		return X86_BR_NONE;
	}

	return X86_BR_NONE;
}

/*
 * return the type of control flow change at address "from"
 * instruction is not necessarily a branch (in case of interrupt).
 *
 * The branch type returned also includes the priv level of the
 * target of the control flow change (X86_BR_USER, X86_BR_KERNEL).
 *
 * If a branch type is unknown OR the instruction cannot be
 * decoded (e.g., text page not present), then X86_BR_NONE is
 * returned.
 *
 * While recording branches, some processors can report the "from"
 * address to be that of an instruction preceding the actual branch
 * when instruction fusion occurs. If fusion is expected, attempt to
 * find the type of the first branch instruction within the next
 * MAX_INSN_SIZE bytes and if found, provide the offset between the
 * reported "from" address and the actual branch instruction address.
 */
static int get_branch_type(unsigned long from, unsigned long to, int abort,
			   bool fused, int *offset)
{
	struct insn insn;
	void *addr;
	int bytes_read, bytes_left, insn_offset;
	int ret = X86_BR_NONE;
	int to_plm, from_plm;
	u8 buf[MAX_INSN_SIZE];
	int is64 = 0;

	/* make sure we initialize offset */
	if (offset)
		*offset = 0;

	to_plm = kernel_ip(to) ? X86_BR_KERNEL : X86_BR_USER;
	from_plm = kernel_ip(from) ? X86_BR_KERNEL : X86_BR_USER;

	/*
	 * maybe zero if lbr did not fill up after a reset by the time
	 * we get a PMU interrupt
	 */
	if (from == 0 || to == 0)
		return X86_BR_NONE;

	if (abort)
		return X86_BR_ABORT | to_plm;

	if (from_plm == X86_BR_USER) {
		/*
		 * can happen if measuring at the user level only
		 * and we interrupt in a kernel thread, e.g., idle.
		 */
		if (!current->mm)
			return X86_BR_NONE;

		/* may fail if text not present */
		bytes_left = copy_from_user_nmi(buf, (void __user *)from,
						MAX_INSN_SIZE);
		bytes_read = MAX_INSN_SIZE - bytes_left;
		if (!bytes_read)
			return X86_BR_NONE;

		addr = buf;
	} else {
		/*
		 * The LBR logs any address in the IP, even if the IP just
		 * faulted. This means userspace can control the from address.
		 * Ensure we don't blindly read any address by validating it is
		 * a known text address.
		 */
		if (kernel_text_address(from)) {
			addr = (void *)from;
			/*
			 * Assume we can get the maximum possible size
			 * when grabbing kernel data.  This is not
			 * _strictly_ true since we could possibly be
			 * executing up next to a memory hole, but
			 * it is very unlikely to be a problem.
			 */
			bytes_read = MAX_INSN_SIZE;
		} else {
			return X86_BR_NONE;
		}
	}

	/*
	 * decoder needs to know the ABI especially
	 * on 64-bit systems running 32-bit apps
	 */
#ifdef CONFIG_X86_64
	is64 = kernel_ip((unsigned long)addr) || any_64bit_mode(current_pt_regs());
#endif
	insn_init(&insn, addr, bytes_read, is64);
	ret = decode_branch_type(&insn);
	insn_offset = 0;

	/* Check for the possibility of branch fusion */
	while (fused && ret == X86_BR_NONE) {
		/* Check for decoding errors */
		if (insn_get_length(&insn) || !insn.length)
			break;

		insn_offset += insn.length;
		bytes_read -= insn.length;
		if (bytes_read < 0)
			break;

		insn_init(&insn, addr + insn_offset, bytes_read, is64);
		ret = decode_branch_type(&insn);
	}

	if (offset)
		*offset = insn_offset;

	/*
	 * interrupts, traps, faults (and thus ring transition) may
	 * occur on any instructions. Thus, to classify them correctly,
	 * we need to first look at the from and to priv levels. If they
	 * are different and to is in the kernel, then it indicates
	 * a ring transition. If the from instruction is not a ring
	 * transition instr (syscall, systenter, int), then it means
	 * it was a irq, trap or fault.
	 *
	 * we have no way of detecting kernel to kernel faults.
	 */
	if (from_plm == X86_BR_USER && to_plm == X86_BR_KERNEL
	    && ret != X86_BR_SYSCALL && ret != X86_BR_INT)
		ret = X86_BR_IRQ;

	/*
	 * branch priv level determined by target as
	 * is done by HW when LBR_SELECT is implemented
	 */
	if (ret != X86_BR_NONE)
		ret |= to_plm;

	return ret;
}

int branch_type(unsigned long from, unsigned long to, int abort)
{
	return get_branch_type(from, to, abort, false, NULL);
}

int branch_type_fused(unsigned long from, unsigned long to, int abort,
		      int *offset)
{
	return get_branch_type(from, to, abort, true, offset);
}

#define X86_BR_TYPE_MAP_MAX	16

static int branch_map[X86_BR_TYPE_MAP_MAX] = {
	PERF_BR_CALL,		/* X86_BR_CALL */
	PERF_BR_RET,		/* X86_BR_RET */
	PERF_BR_SYSCALL,	/* X86_BR_SYSCALL */
	PERF_BR_SYSRET,		/* X86_BR_SYSRET */
	PERF_BR_UNKNOWN,	/* X86_BR_INT */
	PERF_BR_ERET,		/* X86_BR_IRET */
	PERF_BR_COND,		/* X86_BR_JCC */
	PERF_BR_UNCOND,		/* X86_BR_JMP */
	PERF_BR_IRQ,		/* X86_BR_IRQ */
	PERF_BR_IND_CALL,	/* X86_BR_IND_CALL */
	PERF_BR_UNKNOWN,	/* X86_BR_ABORT */
	PERF_BR_UNKNOWN,	/* X86_BR_IN_TX */
	PERF_BR_NO_TX,		/* X86_BR_NO_TX */
	PERF_BR_CALL,		/* X86_BR_ZERO_CALL */
	PERF_BR_UNKNOWN,	/* X86_BR_CALL_STACK */
	PERF_BR_IND,		/* X86_BR_IND_JMP */
};

int common_branch_type(int type)
{
	int i;

	type >>= 2; /* skip X86_BR_USER and X86_BR_KERNEL */

	if (type) {
		i = __ffs(type);
		if (i < X86_BR_TYPE_MAP_MAX)
			return branch_map[i];
	}

	return PERF_BR_UNKNOWN;
}
