// SPDX-License-Identifier: GPL-2.01#include <asm/insn.h>2#include <linux/mm.h>34#include <asm/msr.h>5#include "perf_event.h"67static int decode_branch_type(struct insn *insn)8{9int ext;1011if (insn_get_opcode(insn))12return X86_BR_ABORT;1314switch (insn->opcode.bytes[0]) {15case 0xf:16switch (insn->opcode.bytes[1]) {17case 0x05: /* syscall */18case 0x34: /* sysenter */19return X86_BR_SYSCALL;20case 0x07: /* sysret */21case 0x35: /* sysexit */22return X86_BR_SYSRET;23case 0x80 ... 0x8f: /* conditional */24return X86_BR_JCC;25}26return X86_BR_NONE;27case 0x70 ... 0x7f: /* conditional */28return X86_BR_JCC;29case 0xc2: /* near ret */30case 0xc3: /* near ret */31case 0xca: /* far ret */32case 0xcb: /* far ret */33return X86_BR_RET;34case 0xcf: /* iret */35return X86_BR_IRET;36case 0xcc ... 0xce: /* int */37return X86_BR_INT;38case 0xe8: /* call near rel */39if (insn_get_immediate(insn) || insn->immediate1.value == 0) {40/* zero length call */41return X86_BR_ZERO_CALL;42}43fallthrough;44case 0x9a: /* call far absolute */45return X86_BR_CALL;46case 0xe0 ... 0xe3: /* loop jmp */47return X86_BR_JCC;48case 0xe9 ... 0xeb: /* jmp */49return X86_BR_JMP;50case 0xff: /* call near absolute, call far absolute ind */51if (insn_get_modrm(insn))52return X86_BR_ABORT;5354ext = (insn->modrm.bytes[0] >> 3) & 0x7;55switch (ext) {56case 2: /* near ind call */57case 3: /* far ind call */58return X86_BR_IND_CALL;59case 4:60case 5:61return X86_BR_IND_JMP;62}63return X86_BR_NONE;64}6566return X86_BR_NONE;67}6869/*70* return the type of control flow change at address "from"71* instruction is not necessarily a branch (in case of interrupt).72*73* The branch type returned also includes the priv level of the74* target of the control flow change (X86_BR_USER, X86_BR_KERNEL).75*76* If a branch type is unknown OR the instruction cannot be77* decoded (e.g., text page not present), then X86_BR_NONE is78* returned.79*80* While recording branches, some processors can report the "from"81* address to be that of an instruction preceding the actual branch82* when instruction fusion occurs. If fusion is expected, attempt to83* find the type of the first branch instruction within the next84* MAX_INSN_SIZE bytes and if found, provide the offset between the85* reported "from" address and the actual branch instruction address.86*/87static int get_branch_type(unsigned long from, unsigned long to, int abort,88bool fused, int *offset)89{90struct insn insn;91void *addr;92int bytes_read, bytes_left, insn_offset;93int ret = X86_BR_NONE;94int to_plm, from_plm;95u8 buf[MAX_INSN_SIZE];96int is64 = 0;9798/* make sure we initialize offset */99if (offset)100*offset = 0;101102to_plm = kernel_ip(to) ? X86_BR_KERNEL : X86_BR_USER;103from_plm = kernel_ip(from) ? X86_BR_KERNEL : X86_BR_USER;104105/*106* maybe zero if lbr did not fill up after a reset by the time107* we get a PMU interrupt108*/109if (from == 0 || to == 0)110return X86_BR_NONE;111112if (abort)113return X86_BR_ABORT | to_plm;114115if (from_plm == X86_BR_USER) {116/*117* can happen if measuring at the user level only118* and we interrupt in a kernel thread, e.g., idle.119*/120if (!current->mm)121return X86_BR_NONE;122123/* may fail if text not present */124bytes_left = copy_from_user_nmi(buf, (void __user *)from,125MAX_INSN_SIZE);126bytes_read = MAX_INSN_SIZE - bytes_left;127if (!bytes_read)128return X86_BR_NONE;129130addr = buf;131} else {132/*133* The LBR logs any address in the IP, even if the IP just134* faulted. This means userspace can control the from address.135* Ensure we don't blindly read any address by validating it is136* a known text address and not a vsyscall address.137*/138if (kernel_text_address(from) && !in_gate_area_no_mm(from)) {139addr = (void *)from;140/*141* Assume we can get the maximum possible size142* when grabbing kernel data. This is not143* _strictly_ true since we could possibly be144* executing up next to a memory hole, but145* it is very unlikely to be a problem.146*/147bytes_read = MAX_INSN_SIZE;148} else {149return X86_BR_NONE;150}151}152153/*154* decoder needs to know the ABI especially155* on 64-bit systems running 32-bit apps156*/157#ifdef CONFIG_X86_64158is64 = kernel_ip((unsigned long)addr) || any_64bit_mode(current_pt_regs());159#endif160insn_init(&insn, addr, bytes_read, is64);161ret = decode_branch_type(&insn);162insn_offset = 0;163164/* Check for the possibility of branch fusion */165while (fused && ret == X86_BR_NONE) {166/* Check for decoding errors */167if (insn_get_length(&insn) || !insn.length)168break;169170insn_offset += insn.length;171bytes_read -= insn.length;172if (bytes_read < 0)173break;174175insn_init(&insn, addr + insn_offset, bytes_read, is64);176ret = decode_branch_type(&insn);177}178179if (offset)180*offset = insn_offset;181182/*183* interrupts, traps, faults (and thus ring transition) may184* occur on any instructions. Thus, to classify them correctly,185* we need to first look at the from and to priv levels. If they186* are different and to is in the kernel, then it indicates187* a ring transition. If the from instruction is not a ring188* transition instr (syscall, systenter, int), then it means189* it was a irq, trap or fault.190*191* we have no way of detecting kernel to kernel faults.192*/193if (from_plm == X86_BR_USER && to_plm == X86_BR_KERNEL194&& ret != X86_BR_SYSCALL && ret != X86_BR_INT)195ret = X86_BR_IRQ;196197/*198* branch priv level determined by target as199* is done by HW when LBR_SELECT is implemented200*/201if (ret != X86_BR_NONE)202ret |= to_plm;203204return ret;205}206207int branch_type(unsigned long from, unsigned long to, int abort)208{209return get_branch_type(from, to, abort, false, NULL);210}211212int branch_type_fused(unsigned long from, unsigned long to, int abort,213int *offset)214{215return get_branch_type(from, to, abort, true, offset);216}217218#define X86_BR_TYPE_MAP_MAX 16219220static int branch_map[X86_BR_TYPE_MAP_MAX] = {221PERF_BR_CALL, /* X86_BR_CALL */222PERF_BR_RET, /* X86_BR_RET */223PERF_BR_SYSCALL, /* X86_BR_SYSCALL */224PERF_BR_SYSRET, /* X86_BR_SYSRET */225PERF_BR_UNKNOWN, /* X86_BR_INT */226PERF_BR_ERET, /* X86_BR_IRET */227PERF_BR_COND, /* X86_BR_JCC */228PERF_BR_UNCOND, /* X86_BR_JMP */229PERF_BR_IRQ, /* X86_BR_IRQ */230PERF_BR_IND_CALL, /* X86_BR_IND_CALL */231PERF_BR_UNKNOWN, /* X86_BR_ABORT */232PERF_BR_UNKNOWN, /* X86_BR_IN_TX */233PERF_BR_NO_TX, /* X86_BR_NO_TX */234PERF_BR_CALL, /* X86_BR_ZERO_CALL */235PERF_BR_UNKNOWN, /* X86_BR_CALL_STACK */236PERF_BR_IND, /* X86_BR_IND_JMP */237};238239int common_branch_type(int type)240{241int i;242243type >>= 2; /* skip X86_BR_USER and X86_BR_KERNEL */244245if (type) {246i = __ffs(type);247if (i < X86_BR_TYPE_MAP_MAX)248return branch_map[i];249}250251return PERF_BR_UNKNOWN;252}253254255