Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * Intel(R) Processor Trace PMU driver for perf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  * Copyright (c) 2013-2014, Intel Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * Intel PT is specified in the Intel Architecture Instruction Set Extensions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * Programming Reference:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  * http://software.intel.com/en-us/intel-isa-extensions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #undef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <asm/perf_event.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <asm/insn.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <asm/intel_pt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <asm/intel-family.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include "../perf_event.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include "pt.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) static DEFINE_PER_CPU(struct pt, pt_ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) static struct pt_pmu pt_pmu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33)  * Capabilities of Intel PT hardware, such as number of address bits or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34)  * supported output schemes, are cached and exported to userspace as "caps"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35)  * attribute group of pt pmu device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36)  * (/sys/bus/event_source/devices/intel_pt/caps/) so that userspace can store
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37)  * relevant bits together with intel_pt traces.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39)  * These are necessary for both trace decoding (payloads_lip, contains address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40)  * width encoded in IP-related packets), and event configuration (bitmasks with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41)  * permitted values for certain bit fields).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #define PT_CAP(_n, _l, _r, _m)						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 	[PT_CAP_ ## _n] = { .name = __stringify(_n), .leaf = _l,	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 			    .reg = _r, .mask = _m }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) static struct pt_cap_desc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 	const char	*name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 	u32		leaf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 	u8		reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 	u32		mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) } pt_caps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 	PT_CAP(max_subleaf,		0, CPUID_EAX, 0xffffffff),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 	PT_CAP(cr3_filtering,		0, CPUID_EBX, BIT(0)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 	PT_CAP(psb_cyc,			0, CPUID_EBX, BIT(1)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 	PT_CAP(ip_filtering,		0, CPUID_EBX, BIT(2)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 	PT_CAP(mtc,			0, CPUID_EBX, BIT(3)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 	PT_CAP(ptwrite,			0, CPUID_EBX, BIT(4)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 	PT_CAP(power_event_trace,	0, CPUID_EBX, BIT(5)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 	PT_CAP(topa_output,		0, CPUID_ECX, BIT(0)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 	PT_CAP(topa_multiple_entries,	0, CPUID_ECX, BIT(1)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 	PT_CAP(single_range_output,	0, CPUID_ECX, BIT(2)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 	PT_CAP(output_subsys,		0, CPUID_ECX, BIT(3)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 	PT_CAP(payloads_lip,		0, CPUID_ECX, BIT(31)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 	PT_CAP(num_address_ranges,	1, CPUID_EAX, 0x7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 	PT_CAP(mtc_periods,		1, CPUID_EAX, 0xffff0000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 	PT_CAP(cycle_thresholds,	1, CPUID_EBX, 0xffff),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 	PT_CAP(psb_periods,		1, CPUID_EBX, 0xffff0000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) u32 intel_pt_validate_cap(u32 *caps, enum pt_capabilities capability)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	struct pt_cap_desc *cd = &pt_caps[capability];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 	u32 c = caps[cd->leaf * PT_CPUID_REGS_NUM + cd->reg];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 	unsigned int shift = __ffs(cd->mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	return (c & cd->mask) >> shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) EXPORT_SYMBOL_GPL(intel_pt_validate_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) u32 intel_pt_validate_hw_cap(enum pt_capabilities cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	return intel_pt_validate_cap(pt_pmu.caps, cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) EXPORT_SYMBOL_GPL(intel_pt_validate_hw_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) static ssize_t pt_cap_show(struct device *cdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 			   struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 			   char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	struct dev_ext_attribute *ea =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 		container_of(attr, struct dev_ext_attribute, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	enum pt_capabilities cap = (long)ea->var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	return snprintf(buf, PAGE_SIZE, "%x\n", intel_pt_validate_hw_cap(cap));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) static struct attribute_group pt_cap_group __ro_after_init = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	.name	= "caps",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) PMU_FORMAT_ATTR(pt,		"config:0"	);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) PMU_FORMAT_ATTR(cyc,		"config:1"	);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) PMU_FORMAT_ATTR(pwr_evt,	"config:4"	);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) PMU_FORMAT_ATTR(fup_on_ptw,	"config:5"	);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) PMU_FORMAT_ATTR(mtc,		"config:9"	);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) PMU_FORMAT_ATTR(tsc,		"config:10"	);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) PMU_FORMAT_ATTR(noretcomp,	"config:11"	);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) PMU_FORMAT_ATTR(ptw,		"config:12"	);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) PMU_FORMAT_ATTR(branch,		"config:13"	);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) PMU_FORMAT_ATTR(mtc_period,	"config:14-17"	);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) PMU_FORMAT_ATTR(cyc_thresh,	"config:19-22"	);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) PMU_FORMAT_ATTR(psb_period,	"config:24-27"	);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) static struct attribute *pt_formats_attr[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	&format_attr_pt.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	&format_attr_cyc.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	&format_attr_pwr_evt.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	&format_attr_fup_on_ptw.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	&format_attr_mtc.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	&format_attr_tsc.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	&format_attr_noretcomp.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	&format_attr_ptw.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	&format_attr_branch.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	&format_attr_mtc_period.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	&format_attr_cyc_thresh.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	&format_attr_psb_period.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) static struct attribute_group pt_format_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	.name	= "format",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	.attrs	= pt_formats_attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) pt_timing_attr_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 		    char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	struct perf_pmu_events_attr *pmu_attr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 		container_of(attr, struct perf_pmu_events_attr, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	switch (pmu_attr->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 		return sprintf(page, "%lu\n", pt_pmu.max_nonturbo_ratio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 		return sprintf(page, "%u:%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 			       pt_pmu.tsc_art_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 			       pt_pmu.tsc_art_den);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) PMU_EVENT_ATTR(max_nonturbo_ratio, timing_attr_max_nonturbo_ratio, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	       pt_timing_attr_show);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) PMU_EVENT_ATTR(tsc_art_ratio, timing_attr_tsc_art_ratio, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	       pt_timing_attr_show);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) static struct attribute *pt_timing_attr[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	&timing_attr_max_nonturbo_ratio.attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	&timing_attr_tsc_art_ratio.attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) static struct attribute_group pt_timing_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	.attrs	= pt_timing_attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) static const struct attribute_group *pt_attr_groups[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	&pt_cap_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	&pt_format_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	&pt_timing_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) static int __init pt_pmu_hw_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	struct dev_ext_attribute *de_attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	struct attribute **attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	size_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	u64 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	long i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	rdmsrl(MSR_PLATFORM_INFO, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	pt_pmu.max_nonturbo_ratio = (reg & 0xff00) >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	 * if available, read in TSC to core crystal clock ratio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	 * otherwise, zero for numerator stands for "not enumerated"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	 * as per SDM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	if (boot_cpu_data.cpuid_level >= CPUID_TSC_LEAF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 		u32 eax, ebx, ecx, edx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 		cpuid(CPUID_TSC_LEAF, &eax, &ebx, &ecx, &edx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 		pt_pmu.tsc_art_num = ebx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 		pt_pmu.tsc_art_den = eax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	/* model-specific quirks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	switch (boot_cpu_data.x86_model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	case INTEL_FAM6_BROADWELL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	case INTEL_FAM6_BROADWELL_D:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	case INTEL_FAM6_BROADWELL_G:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	case INTEL_FAM6_BROADWELL_X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 		/* not setting BRANCH_EN will #GP, erratum BDM106 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 		pt_pmu.branch_en_always_on = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	if (boot_cpu_has(X86_FEATURE_VMX)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 		 * Intel SDM, 36.5 "Tracing post-VMXON" says that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 		 * "IA32_VMX_MISC[bit 14]" being 1 means PT can trace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 		 * post-VMXON.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 		rdmsrl(MSR_IA32_VMX_MISC, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 		if (reg & BIT(14))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 			pt_pmu.vmx = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	for (i = 0; i < PT_CPUID_LEAVES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 		cpuid_count(20, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 			    &pt_pmu.caps[CPUID_EAX + i*PT_CPUID_REGS_NUM],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 			    &pt_pmu.caps[CPUID_EBX + i*PT_CPUID_REGS_NUM],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 			    &pt_pmu.caps[CPUID_ECX + i*PT_CPUID_REGS_NUM],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 			    &pt_pmu.caps[CPUID_EDX + i*PT_CPUID_REGS_NUM]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	size = sizeof(struct attribute *) * (ARRAY_SIZE(pt_caps)+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	attrs = kzalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	if (!attrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	size = sizeof(struct dev_ext_attribute) * (ARRAY_SIZE(pt_caps)+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	de_attrs = kzalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	if (!de_attrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	for (i = 0; i < ARRAY_SIZE(pt_caps); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 		struct dev_ext_attribute *de_attr = de_attrs + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 		de_attr->attr.attr.name = pt_caps[i].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 		sysfs_attr_init(&de_attr->attr.attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 		de_attr->attr.attr.mode		= S_IRUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 		de_attr->attr.show		= pt_cap_show;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 		de_attr->var			= (void *)i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 		attrs[i] = &de_attr->attr.attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	pt_cap_group.attrs = attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	kfree(attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) #define RTIT_CTL_CYC_PSB (RTIT_CTL_CYCLEACC	| \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 			  RTIT_CTL_CYC_THRESH	| \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 			  RTIT_CTL_PSB_FREQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) #define RTIT_CTL_MTC	(RTIT_CTL_MTC_EN	| \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 			 RTIT_CTL_MTC_RANGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) #define RTIT_CTL_PTW	(RTIT_CTL_PTW_EN	| \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 			 RTIT_CTL_FUP_ON_PTW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283)  * Bit 0 (TraceEn) in the attr.config is meaningless as the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284)  * corresponding bit in the RTIT_CTL can only be controlled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285)  * by the driver; therefore, repurpose it to mean: pass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286)  * through the bit that was previously assumed to be always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287)  * on for PT, thereby allowing the user to *not* set it if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288)  * they so wish. See also pt_event_valid() and pt_config().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) #define RTIT_CTL_PASSTHROUGH RTIT_CTL_TRACEEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) #define PT_CONFIG_MASK (RTIT_CTL_TRACEEN	| \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 			RTIT_CTL_TSC_EN		| \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 			RTIT_CTL_DISRETC	| \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 			RTIT_CTL_BRANCH_EN	| \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 			RTIT_CTL_CYC_PSB	| \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 			RTIT_CTL_MTC		| \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 			RTIT_CTL_PWR_EVT_EN	| \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 			RTIT_CTL_FUP_ON_PTW	| \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 			RTIT_CTL_PTW_EN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) static bool pt_event_valid(struct perf_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	u64 config = event->attr.config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	u64 allowed, requested;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	if ((config & PT_CONFIG_MASK) != config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	if (config & RTIT_CTL_CYC_PSB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 		if (!intel_pt_validate_hw_cap(PT_CAP_psb_cyc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 		allowed = intel_pt_validate_hw_cap(PT_CAP_psb_periods);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 		requested = (config & RTIT_CTL_PSB_FREQ) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 			RTIT_CTL_PSB_FREQ_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 		if (requested && (!(allowed & BIT(requested))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 		allowed = intel_pt_validate_hw_cap(PT_CAP_cycle_thresholds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 		requested = (config & RTIT_CTL_CYC_THRESH) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 			RTIT_CTL_CYC_THRESH_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 		if (requested && (!(allowed & BIT(requested))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	if (config & RTIT_CTL_MTC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 		 * In the unlikely case that CPUID lists valid mtc periods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 		 * but not the mtc capability, drop out here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 		 * Spec says that setting mtc period bits while mtc bit in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 		 * CPUID is 0 will #GP, so better safe than sorry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 		if (!intel_pt_validate_hw_cap(PT_CAP_mtc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 		allowed = intel_pt_validate_hw_cap(PT_CAP_mtc_periods);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 		if (!allowed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 		requested = (config & RTIT_CTL_MTC_RANGE) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 			RTIT_CTL_MTC_RANGE_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 		if (!(allowed & BIT(requested)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	if (config & RTIT_CTL_PWR_EVT_EN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	    !intel_pt_validate_hw_cap(PT_CAP_power_event_trace))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	if (config & RTIT_CTL_PTW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 		if (!intel_pt_validate_hw_cap(PT_CAP_ptwrite))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 		/* FUPonPTW without PTW doesn't make sense */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 		if ((config & RTIT_CTL_FUP_ON_PTW) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 		    !(config & RTIT_CTL_PTW_EN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	 * Setting bit 0 (TraceEn in RTIT_CTL MSR) in the attr.config
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	 * clears the assomption that BranchEn must always be enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	 * as was the case with the first implementation of PT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	 * If this bit is not set, the legacy behavior is preserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	 * for compatibility with the older userspace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	 * Re-using bit 0 for this purpose is fine because it is never
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	 * directly set by the user; previous attempts at setting it in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	 * the attr.config resulted in -EINVAL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	if (config & RTIT_CTL_PASSTHROUGH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 		 * Disallow not setting BRANCH_EN where BRANCH_EN is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 		 * always required.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 		if (pt_pmu.branch_en_always_on &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 		    !(config & RTIT_CTL_BRANCH_EN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 		 * Disallow BRANCH_EN without the PASSTHROUGH.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 		if (config & RTIT_CTL_BRANCH_EN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394)  * PT configuration helpers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395)  * These all are cpu affine and operate on a local PT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) static void pt_config_start(struct perf_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	struct pt *pt = this_cpu_ptr(&pt_ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	u64 ctl = event->hw.config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	ctl |= RTIT_CTL_TRACEEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	if (READ_ONCE(pt->vmx_on))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 		perf_aux_output_flag(&pt->handle, PERF_AUX_FLAG_PARTIAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 		wrmsrl(MSR_IA32_RTIT_CTL, ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	WRITE_ONCE(event->hw.config, ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) /* Address ranges and their corresponding msr configuration registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) static const struct pt_address_range {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	unsigned long	msr_a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	unsigned long	msr_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	unsigned int	reg_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) } pt_address_ranges[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 		.msr_a	 = MSR_IA32_RTIT_ADDR0_A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 		.msr_b	 = MSR_IA32_RTIT_ADDR0_B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 		.reg_off = RTIT_CTL_ADDR0_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 		.msr_a	 = MSR_IA32_RTIT_ADDR1_A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 		.msr_b	 = MSR_IA32_RTIT_ADDR1_B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 		.reg_off = RTIT_CTL_ADDR1_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 		.msr_a	 = MSR_IA32_RTIT_ADDR2_A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 		.msr_b	 = MSR_IA32_RTIT_ADDR2_B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 		.reg_off = RTIT_CTL_ADDR2_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 		.msr_a	 = MSR_IA32_RTIT_ADDR3_A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 		.msr_b	 = MSR_IA32_RTIT_ADDR3_B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 		.reg_off = RTIT_CTL_ADDR3_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) static u64 pt_config_filters(struct perf_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	struct pt_filters *filters = event->hw.addr_filters;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	struct pt *pt = this_cpu_ptr(&pt_ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	unsigned int range = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	u64 rtit_ctl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	if (!filters)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	perf_event_addr_filters_sync(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	for (range = 0; range < filters->nr_filters; range++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 		struct pt_filter *filter = &filters->filter[range];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 		 * Note, if the range has zero start/end addresses due
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 		 * to its dynamic object not being loaded yet, we just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 		 * go ahead and program zeroed range, which will simply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 		 * produce no data. Note^2: if executable code at 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 		 * is a concern, we can set up an "invalid" configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 		 * such as msr_b < msr_a.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 		/* avoid redundant msr writes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 		if (pt->filters.filter[range].msr_a != filter->msr_a) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 			wrmsrl(pt_address_ranges[range].msr_a, filter->msr_a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 			pt->filters.filter[range].msr_a = filter->msr_a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 		if (pt->filters.filter[range].msr_b != filter->msr_b) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 			wrmsrl(pt_address_ranges[range].msr_b, filter->msr_b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 			pt->filters.filter[range].msr_b = filter->msr_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 		rtit_ctl |= (u64)filter->config << pt_address_ranges[range].reg_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	return rtit_ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) static void pt_config(struct perf_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	struct pt *pt = this_cpu_ptr(&pt_ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	struct pt_buffer *buf = perf_get_aux(&pt->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	u64 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	/* First round: clear STATUS, in particular the PSB byte counter. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	if (!event->hw.config) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 		perf_event_itrace_started(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 		wrmsrl(MSR_IA32_RTIT_STATUS, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	reg = pt_config_filters(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	reg |= RTIT_CTL_TRACEEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	if (!buf->single)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 		reg |= RTIT_CTL_TOPA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	 * Previously, we had BRANCH_EN on by default, but now that PT has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	 * grown features outside of branch tracing, it is useful to allow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	 * the user to disable it. Setting bit 0 in the event's attr.config
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	 * allows BRANCH_EN to pass through instead of being always on. See
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	 * also the comment in pt_event_valid().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	if (event->attr.config & BIT(0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 		reg |= event->attr.config & RTIT_CTL_BRANCH_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 		reg |= RTIT_CTL_BRANCH_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	if (!event->attr.exclude_kernel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 		reg |= RTIT_CTL_OS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	if (!event->attr.exclude_user)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 		reg |= RTIT_CTL_USR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	reg |= (event->attr.config & PT_CONFIG_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	event->hw.config = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	pt_config_start(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) static void pt_config_stop(struct perf_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	struct pt *pt = this_cpu_ptr(&pt_ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	u64 ctl = READ_ONCE(event->hw.config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	/* may be already stopped by a PMI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	if (!(ctl & RTIT_CTL_TRACEEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	ctl &= ~RTIT_CTL_TRACEEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	if (!READ_ONCE(pt->vmx_on))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 		wrmsrl(MSR_IA32_RTIT_CTL, ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	WRITE_ONCE(event->hw.config, ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	 * A wrmsr that disables trace generation serializes other PT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	 * registers and causes all data packets to be written to memory,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	 * but a fence is required for the data to become globally visible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	 * The below WMB, separating data store and aux_head store matches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	 * the consumer's RMB that separates aux_head load and data load.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549)  * struct topa - ToPA metadata
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550)  * @list:	linkage to struct pt_buffer's list of tables
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551)  * @offset:	offset of the first entry in this table in the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552)  * @size:	total size of all entries in this table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553)  * @last:	index of the last initialized entry in this table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554)  * @z_count:	how many times the first entry repeats
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) struct topa {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	struct list_head	list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	u64			offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	size_t			size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	int			last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	unsigned int		z_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565)  * Keep ToPA table-related metadata on the same page as the actual table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566)  * taking up a few words from the top
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) #define TENTS_PER_PAGE	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	((PAGE_SIZE - sizeof(struct topa)) / sizeof(struct topa_entry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573)  * struct topa_page - page-sized ToPA table with metadata at the top
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574)  * @table:	actual ToPA table entries, as understood by PT hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575)  * @topa:	metadata
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) struct topa_page {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	struct topa_entry	table[TENTS_PER_PAGE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	struct topa		topa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) static inline struct topa_page *topa_to_page(struct topa *topa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	return container_of(topa, struct topa_page, topa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) static inline struct topa_page *topa_entry_to_page(struct topa_entry *te)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	return (struct topa_page *)((unsigned long)te & PAGE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) static inline phys_addr_t topa_pfn(struct topa *topa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	return PFN_DOWN(virt_to_phys(topa_to_page(topa)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) /* make -1 stand for the last table entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) #define TOPA_ENTRY(t, i)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	((i) == -1					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 		? &topa_to_page(t)->table[(t)->last]	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 		: &topa_to_page(t)->table[(i)])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) #define TOPA_ENTRY_SIZE(t, i) (sizes(TOPA_ENTRY((t), (i))->size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) #define TOPA_ENTRY_PAGES(t, i) (1 << TOPA_ENTRY((t), (i))->size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) static void pt_config_buffer(struct pt_buffer *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	struct pt *pt = this_cpu_ptr(&pt_ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	u64 reg, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	void *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	if (buf->single) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 		base = buf->data_pages[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 		mask = (buf->nr_pages * PAGE_SIZE - 1) >> 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 		base = topa_to_page(buf->cur)->table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 		mask = (u64)buf->cur_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	reg = virt_to_phys(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	if (pt->output_base != reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 		pt->output_base = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 		wrmsrl(MSR_IA32_RTIT_OUTPUT_BASE, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	reg = 0x7f | (mask << 7) | ((u64)buf->output_off << 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	if (pt->output_mask != reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 		pt->output_mask = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 		wrmsrl(MSR_IA32_RTIT_OUTPUT_MASK, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633)  * topa_alloc() - allocate page-sized ToPA table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634)  * @cpu:	CPU on which to allocate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635)  * @gfp:	Allocation flags.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637)  * Return:	On success, return the pointer to ToPA table page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) static struct topa *topa_alloc(int cpu, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	int node = cpu_to_node(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	struct topa_page *tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	struct page *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	p = alloc_pages_node(node, gfp | __GFP_ZERO, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	tp = page_address(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	tp->topa.last = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	 * In case of singe-entry ToPA, always put the self-referencing END
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	 * link as the 2nd entry in the table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	if (!intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 		TOPA_ENTRY(&tp->topa, 1)->base = page_to_phys(p) >> TOPA_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 		TOPA_ENTRY(&tp->topa, 1)->end = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 	return &tp->topa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665)  * topa_free() - free a page-sized ToPA table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666)  * @topa:	Table to deallocate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) static void topa_free(struct topa *topa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	free_page((unsigned long)topa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674)  * topa_insert_table() - insert a ToPA table into a buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675)  * @buf:	 PT buffer that's being extended.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676)  * @topa:	 New topa table to be inserted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678)  * If it's the first table in this buffer, set up buffer's pointers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679)  * accordingly; otherwise, add a END=1 link entry to @topa to the current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680)  * "last" table and adjust the last table pointer to @topa.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) static void topa_insert_table(struct pt_buffer *buf, struct topa *topa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	struct topa *last = buf->last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	list_add_tail(&topa->list, &buf->tables);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	if (!buf->first) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 		buf->first = buf->last = buf->cur = topa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 	topa->offset = last->offset + last->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	buf->last = topa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	if (!intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	BUG_ON(last->last != TENTS_PER_PAGE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	TOPA_ENTRY(last, -1)->base = topa_pfn(topa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	TOPA_ENTRY(last, -1)->end = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706)  * topa_table_full() - check if a ToPA table is filled up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707)  * @topa:	ToPA table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) static bool topa_table_full(struct topa *topa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	/* single-entry ToPA is a special case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	if (!intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 		return !!topa->last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	return topa->last == TENTS_PER_PAGE - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719)  * topa_insert_pages() - create a list of ToPA tables
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720)  * @buf:	PT buffer being initialized.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721)  * @gfp:	Allocation flags.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723)  * This initializes a list of ToPA tables with entries from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724)  * the data_pages provided by rb_alloc_aux().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726)  * Return:	0 on success or error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) static int topa_insert_pages(struct pt_buffer *buf, int cpu, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	struct topa *topa = buf->last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	int order = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	struct page *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	p = virt_to_page(buf->data_pages[buf->nr_pages]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	if (PagePrivate(p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 		order = page_private(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	if (topa_table_full(topa)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 		topa = topa_alloc(cpu, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 		if (!topa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 		topa_insert_table(buf, topa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	if (topa->z_count == topa->last - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 		if (order == TOPA_ENTRY(topa, topa->last - 1)->size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 			topa->z_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	TOPA_ENTRY(topa, -1)->base = page_to_phys(p) >> TOPA_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	TOPA_ENTRY(topa, -1)->size = order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	if (!buf->snapshot &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	    !intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 		TOPA_ENTRY(topa, -1)->intr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 		TOPA_ENTRY(topa, -1)->stop = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	topa->last++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	topa->size += sizes(order);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	buf->nr_pages += 1ul << order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768)  * pt_topa_dump() - print ToPA tables and their entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769)  * @buf:	PT buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) static void pt_topa_dump(struct pt_buffer *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	struct topa *topa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	list_for_each_entry(topa, &buf->tables, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 		struct topa_page *tp = topa_to_page(topa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 		int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 		pr_debug("# table @%p, off %llx size %zx\n", tp->table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 			 topa->offset, topa->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 		for (i = 0; i < TENTS_PER_PAGE; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 			pr_debug("# entry @%p (%lx sz %u %c%c%c) raw=%16llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 				 &tp->table[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 				 (unsigned long)tp->table[i].base << TOPA_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 				 sizes(tp->table[i].size),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 				 tp->table[i].end ?  'E' : ' ',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 				 tp->table[i].intr ? 'I' : ' ',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 				 tp->table[i].stop ? 'S' : ' ',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 				 *(u64 *)&tp->table[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 			if ((intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 			     tp->table[i].stop) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 			    tp->table[i].end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 			if (!i && topa->z_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 				i += topa->z_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801)  * pt_buffer_advance() - advance to the next output region
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802)  * @buf:	PT buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804)  * Advance the current pointers in the buffer to the next ToPA entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) static void pt_buffer_advance(struct pt_buffer *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	buf->output_off = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	buf->cur_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	if (buf->cur_idx == buf->cur->last) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 		if (buf->cur == buf->last)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 			buf->cur = buf->first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 			buf->cur = list_entry(buf->cur->list.next, struct topa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 					      list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 		buf->cur_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822)  * pt_update_head() - calculate current offsets and sizes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823)  * @pt:		Per-cpu pt context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825)  * Update buffer's current write pointer position and data size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) static void pt_update_head(struct pt *pt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	struct pt_buffer *buf = perf_get_aux(&pt->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	u64 topa_idx, base, old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 	if (buf->single) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 		local_set(&buf->data_size, buf->output_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	/* offset of the first region in this table from the beginning of buf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	base = buf->cur->offset + buf->output_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	/* offset of the current output region within this table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	for (topa_idx = 0; topa_idx < buf->cur_idx; topa_idx++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 		base += TOPA_ENTRY_SIZE(buf->cur, topa_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	if (buf->snapshot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 		local_set(&buf->data_size, base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 		old = (local64_xchg(&buf->head, base) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 		       ((buf->nr_pages << PAGE_SHIFT) - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 		if (base < old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 			base += buf->nr_pages << PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 		local_add(base - old, &buf->data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857)  * pt_buffer_region() - obtain current output region's address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858)  * @buf:	PT buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) static void *pt_buffer_region(struct pt_buffer *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	return phys_to_virt(TOPA_ENTRY(buf->cur, buf->cur_idx)->base << TOPA_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866)  * pt_buffer_region_size() - obtain current output region's size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867)  * @buf:	PT buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) static size_t pt_buffer_region_size(struct pt_buffer *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	return TOPA_ENTRY_SIZE(buf->cur, buf->cur_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875)  * pt_handle_status() - take care of possible status conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876)  * @pt:		Per-cpu pt context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) static void pt_handle_status(struct pt *pt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	struct pt_buffer *buf = perf_get_aux(&pt->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	int advance = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	u64 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	rdmsrl(MSR_IA32_RTIT_STATUS, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	if (status & RTIT_STATUS_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 		pr_err_ratelimited("ToPA ERROR encountered, trying to recover\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 		pt_topa_dump(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		status &= ~RTIT_STATUS_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	if (status & RTIT_STATUS_STOPPED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 		status &= ~RTIT_STATUS_STOPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 		 * On systems that only do single-entry ToPA, hitting STOP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 		 * means we are already losing data; need to let the decoder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 		 * know.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 		if (!buf->single &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 		    (!intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 		     buf->output_off == pt_buffer_region_size(buf))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 			perf_aux_output_flag(&pt->handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 			                     PERF_AUX_FLAG_TRUNCATED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 			advance++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	 * Also on single-entry ToPA implementations, interrupt will come
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	 * before the output reaches its output region's boundary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	if (!intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	    !buf->snapshot &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	    pt_buffer_region_size(buf) - buf->output_off <= TOPA_PMI_MARGIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 		void *head = pt_buffer_region(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 		/* everything within this margin needs to be zeroed out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 		memset(head + buf->output_off, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 		       pt_buffer_region_size(buf) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 		       buf->output_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 		advance++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	if (advance)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 		pt_buffer_advance(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	wrmsrl(MSR_IA32_RTIT_STATUS, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932)  * pt_read_offset() - translate registers into buffer pointers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933)  * @buf:	PT buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935)  * Set buffer's output pointers from MSR values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) static void pt_read_offset(struct pt_buffer *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	struct pt *pt = this_cpu_ptr(&pt_ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	struct topa_page *tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	if (!buf->single) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 		rdmsrl(MSR_IA32_RTIT_OUTPUT_BASE, pt->output_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 		tp = phys_to_virt(pt->output_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 		buf->cur = &tp->topa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	rdmsrl(MSR_IA32_RTIT_OUTPUT_MASK, pt->output_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	/* offset within current output region */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	buf->output_off = pt->output_mask >> 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	/* index of current output region within this table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	if (!buf->single)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 		buf->cur_idx = (pt->output_mask & 0xffffff80) >> 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) static struct topa_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) pt_topa_entry_for_page(struct pt_buffer *buf, unsigned int pg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	struct topa_page *tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	struct topa *topa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	unsigned int idx, cur_pg = 0, z_pg = 0, start_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	 * Indicates a bug in the caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	if (WARN_ON_ONCE(pg >= buf->nr_pages))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	 * First, find the ToPA table where @pg fits. With high
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 	 * order allocations, there shouldn't be many of these.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	list_for_each_entry(topa, &buf->tables, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 		if (topa->offset + topa->size > pg << PAGE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 			goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	 * Hitting this means we have a problem in the ToPA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	 * allocation code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	 * Indicates a problem in the ToPA allocation code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	if (WARN_ON_ONCE(topa->last == -1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	tp = topa_to_page(topa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	cur_pg = PFN_DOWN(topa->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	if (topa->z_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 		z_pg = TOPA_ENTRY_PAGES(topa, 0) * (topa->z_count + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 		start_idx = topa->z_count + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	 * Multiple entries at the beginning of the table have the same size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	 * ideally all of them; if @pg falls there, the search is done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	if (pg >= cur_pg && pg < cur_pg + z_pg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 		idx = (pg - cur_pg) / TOPA_ENTRY_PAGES(topa, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 		return &tp->table[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	 * Otherwise, slow path: iterate through the remaining entries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	for (idx = start_idx, cur_pg += z_pg; idx < topa->last; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 		if (cur_pg + TOPA_ENTRY_PAGES(topa, idx) > pg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 			return &tp->table[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 		cur_pg += TOPA_ENTRY_PAGES(topa, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	 * Means we couldn't find a ToPA entry in the table that does match.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) static struct topa_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) pt_topa_prev_entry(struct pt_buffer *buf, struct topa_entry *te)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	unsigned long table = (unsigned long)te & ~(PAGE_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	struct topa_page *tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	struct topa *topa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	tp = (struct topa_page *)table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	if (tp->table != te)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 		return --te;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	topa = &tp->topa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 	if (topa == buf->first)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 		topa = buf->last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 		topa = list_prev_entry(topa, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	tp = topa_to_page(topa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 	return &tp->table[topa->last - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)  * pt_buffer_reset_markers() - place interrupt and stop bits in the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)  * @buf:	PT buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)  * @handle:	Current output handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)  * Place INT and STOP marks to prevent overwriting old data that the consumer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)  * hasn't yet collected and waking up the consumer after a certain fraction of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)  * the buffer has filled up. Only needed and sensible for non-snapshot counters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)  * This obviously relies on buf::head to figure out buffer markers, so it has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)  * to be called after pt_buffer_reset_offsets() and before the hardware tracing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)  * is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) static int pt_buffer_reset_markers(struct pt_buffer *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 				   struct perf_output_handle *handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	unsigned long head = local64_read(&buf->head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	unsigned long idx, npages, wakeup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	if (buf->single)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	/* can't stop in the middle of an output region */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	if (buf->output_off + handle->size + 1 < pt_buffer_region_size(buf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 		perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 	/* single entry ToPA is handled by marking all regions STOP=1 INT=1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	if (!intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	/* clear STOP and INT from current entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	if (buf->stop_te) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 		buf->stop_te->stop = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 		buf->stop_te->intr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	if (buf->intr_te)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 		buf->intr_te->intr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	/* how many pages till the STOP marker */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	npages = handle->size >> PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	/* if it's on a page boundary, fill up one more page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	if (!offset_in_page(head + handle->size + 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 		npages++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	idx = (head >> PAGE_SHIFT) + npages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	idx &= buf->nr_pages - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	if (idx != buf->stop_pos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 		buf->stop_pos = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 		buf->stop_te = pt_topa_entry_for_page(buf, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 		buf->stop_te = pt_topa_prev_entry(buf, buf->stop_te);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	wakeup = handle->wakeup >> PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	/* in the worst case, wake up the consumer one page before hard stop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	idx = (head >> PAGE_SHIFT) + npages - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	if (idx > wakeup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 		idx = wakeup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	idx &= buf->nr_pages - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	if (idx != buf->intr_pos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 		buf->intr_pos = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 		buf->intr_te = pt_topa_entry_for_page(buf, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 		buf->intr_te = pt_topa_prev_entry(buf, buf->intr_te);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 	buf->stop_te->stop = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	buf->stop_te->intr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	buf->intr_te->intr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)  * pt_buffer_reset_offsets() - adjust buffer's write pointers from aux_head
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)  * @buf:	PT buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)  * @head:	Write pointer (aux_head) from AUX buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)  * Find the ToPA table and entry corresponding to given @head and set buffer's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)  * "current" pointers accordingly. This is done after we have obtained the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)  * current aux_head position from a successful call to perf_aux_output_begin()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)  * to make sure the hardware is writing to the right place.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)  * This function modifies buf::{cur,cur_idx,output_off} that will be programmed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)  * into PT msrs when the tracing is enabled and buf::head and buf::data_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)  * which are used to determine INT and STOP markers' locations by a subsequent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)  * call to pt_buffer_reset_markers().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) static void pt_buffer_reset_offsets(struct pt_buffer *buf, unsigned long head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	struct topa_page *cur_tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	struct topa_entry *te;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	int pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	if (buf->snapshot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 		head &= (buf->nr_pages << PAGE_SHIFT) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	if (!buf->single) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 		pg = (head >> PAGE_SHIFT) & (buf->nr_pages - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 		te = pt_topa_entry_for_page(buf, pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 		cur_tp = topa_entry_to_page(te);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 		buf->cur = &cur_tp->topa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 		buf->cur_idx = te - TOPA_ENTRY(buf->cur, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 		buf->output_off = head & (pt_buffer_region_size(buf) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 		buf->output_off = head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 	local64_set(&buf->head, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	local_set(&buf->data_size, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)  * pt_buffer_fini_topa() - deallocate ToPA structure of a buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)  * @buf:	PT buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) static void pt_buffer_fini_topa(struct pt_buffer *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 	struct topa *topa, *iter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	if (buf->single)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	list_for_each_entry_safe(topa, iter, &buf->tables, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 		 * right now, this is in free_aux() path only, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 		 * no need to unlink this table from the list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 		topa_free(topa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)  * pt_buffer_init_topa() - initialize ToPA table for pt buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)  * @buf:	PT buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)  * @size:	Total size of all regions within this ToPA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)  * @gfp:	Allocation flags.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) static int pt_buffer_init_topa(struct pt_buffer *buf, int cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 			       unsigned long nr_pages, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	struct topa *topa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	topa = topa_alloc(cpu, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	if (!topa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	topa_insert_table(buf, topa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 	while (buf->nr_pages < nr_pages) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 		err = topa_insert_pages(buf, cpu, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 			pt_buffer_fini_topa(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 	/* link last table to the first one, unless we're double buffering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	if (intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 		TOPA_ENTRY(buf->last, -1)->base = topa_pfn(buf->first);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 		TOPA_ENTRY(buf->last, -1)->end = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	pt_topa_dump(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) static int pt_buffer_try_single(struct pt_buffer *buf, int nr_pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 	struct page *p = virt_to_page(buf->data_pages[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	int ret = -ENOTSUPP, order = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	 * We can use single range output mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	 * + in snapshot mode, where we don't need interrupts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	 * + if the hardware supports it;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	 * + if the entire buffer is one contiguous allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	if (!buf->snapshot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 	if (!intel_pt_validate_hw_cap(PT_CAP_single_range_output))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	if (PagePrivate(p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 		order = page_private(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	if (1 << order != nr_pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 	buf->single = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 	buf->nr_pages = nr_pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)  * pt_buffer_setup_aux() - set up topa tables for a PT buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)  * @cpu:	Cpu on which to allocate, -1 means current.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)  * @pages:	Array of pointers to buffer pages passed from perf core.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)  * @nr_pages:	Number of pages in the buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)  * @snapshot:	If this is a snapshot/overwrite counter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)  * This is a pmu::setup_aux callback that sets up ToPA tables and all the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)  * bookkeeping for an AUX buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)  * Return:	Our private PT buffer structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) static void *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) pt_buffer_setup_aux(struct perf_event *event, void **pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 		    int nr_pages, bool snapshot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 	struct pt_buffer *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 	int node, ret, cpu = event->cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	if (!nr_pages)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 	 * Only support AUX sampling in snapshot mode, where we don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 	 * generate NMIs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 	if (event->attr.aux_sample_size && !snapshot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 	if (cpu == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 		cpu = raw_smp_processor_id();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 	node = cpu_to_node(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 	buf = kzalloc_node(sizeof(struct pt_buffer), GFP_KERNEL, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 	buf->snapshot = snapshot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 	buf->data_pages = pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 	buf->stop_pos = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	buf->intr_pos = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 	INIT_LIST_HEAD(&buf->tables);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 	ret = pt_buffer_try_single(buf, nr_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 		return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	ret = pt_buffer_init_topa(buf, cpu, nr_pages, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 		kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 	return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)  * pt_buffer_free_aux() - perf AUX deallocation path callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)  * @data:	PT buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) static void pt_buffer_free_aux(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	struct pt_buffer *buf = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 	pt_buffer_fini_topa(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 	kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) static int pt_addr_filters_init(struct perf_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 	struct pt_filters *filters;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	int node = event->cpu == -1 ? -1 : cpu_to_node(event->cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 	if (!intel_pt_validate_hw_cap(PT_CAP_num_address_ranges))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 	filters = kzalloc_node(sizeof(struct pt_filters), GFP_KERNEL, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 	if (!filters)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 	if (event->parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 		memcpy(filters, event->parent->hw.addr_filters,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 		       sizeof(*filters));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 	event->hw.addr_filters = filters;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) static void pt_addr_filters_fini(struct perf_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 	kfree(event->hw.addr_filters);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	event->hw.addr_filters = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) static inline bool valid_kernel_ip(unsigned long ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	return virt_addr_valid(ip) && kernel_ip(ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) static int pt_event_addr_filters_validate(struct list_head *filters)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	struct perf_addr_filter *filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	int range = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 	list_for_each_entry(filter, filters, entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 		 * PT doesn't support single address triggers and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 		 * 'start' filters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 		if (!filter->size ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 		    filter->action == PERF_ADDR_FILTER_ACTION_START)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 		if (!filter->path.dentry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 			if (!valid_kernel_ip(filter->offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 			if (!valid_kernel_ip(filter->offset + filter->size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 		if (++range > intel_pt_validate_hw_cap(PT_CAP_num_address_ranges))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 			return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) static void pt_event_addr_filters_sync(struct perf_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 	struct perf_addr_filters_head *head = perf_event_addr_filters(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 	unsigned long msr_a, msr_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 	struct perf_addr_filter_range *fr = event->addr_filter_ranges;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 	struct pt_filters *filters = event->hw.addr_filters;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 	struct perf_addr_filter *filter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 	int range = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 	if (!filters)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 	list_for_each_entry(filter, &head->list, entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 		if (filter->path.dentry && !fr[range].start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 			msr_a = msr_b = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 			/* apply the offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 			msr_a = fr[range].start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 			msr_b = msr_a + fr[range].size - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 		filters->filter[range].msr_a  = msr_a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 		filters->filter[range].msr_b  = msr_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 		if (filter->action == PERF_ADDR_FILTER_ACTION_FILTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 			filters->filter[range].config = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 			filters->filter[range].config = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 		range++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 	filters->nr_filters = range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)  * intel_pt_interrupt() - PT PMI handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) void intel_pt_interrupt(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 	struct pt *pt = this_cpu_ptr(&pt_ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	struct pt_buffer *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 	struct perf_event *event = pt->handle.event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 	 * There may be a dangling PT bit in the interrupt status register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 	 * after PT has been disabled by pt_event_stop(). Make sure we don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 	 * do anything (particularly, re-enable) for this event here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 	if (!READ_ONCE(pt->handle_nmi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 	if (!event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 	pt_config_stop(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 	buf = perf_get_aux(&pt->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 	if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 	pt_read_offset(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 	pt_handle_status(pt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 	pt_update_head(pt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 	perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 	if (!event->hw.state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 		int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 		buf = perf_aux_output_begin(&pt->handle, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 		if (!buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 			event->hw.state = PERF_HES_STOPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 		pt_buffer_reset_offsets(buf, pt->handle.head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 		/* snapshot counters don't use PMI, so it's safe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 		ret = pt_buffer_reset_markers(buf, &pt->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 			perf_aux_output_end(&pt->handle, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 		pt_config_buffer(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 		pt_config_start(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) void intel_pt_handle_vmx(int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 	struct pt *pt = this_cpu_ptr(&pt_ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 	struct perf_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 	/* PT plays nice with VMX, do nothing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 	if (pt_pmu.vmx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 	 * VMXON will clear RTIT_CTL.TraceEn; we need to make
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 	 * sure to not try to set it while VMX is on. Disable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 	 * interrupts to avoid racing with pmu callbacks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 	 * concurrent PMI should be handled fine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 	local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 	WRITE_ONCE(pt->vmx_on, on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 	 * If an AUX transaction is in progress, it will contain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 	 * gap(s), so flag it PARTIAL to inform the user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 	event = pt->handle.event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 	if (event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 		perf_aux_output_flag(&pt->handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 		                     PERF_AUX_FLAG_PARTIAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 	/* Turn PTs back on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 	if (!on && event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 		wrmsrl(MSR_IA32_RTIT_CTL, event->hw.config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 	local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) EXPORT_SYMBOL_GPL(intel_pt_handle_vmx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)  * PMU callbacks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) static void pt_event_start(struct perf_event *event, int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 	struct hw_perf_event *hwc = &event->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 	struct pt *pt = this_cpu_ptr(&pt_ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 	struct pt_buffer *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 	buf = perf_aux_output_begin(&pt->handle, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 	if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 		goto fail_stop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 	pt_buffer_reset_offsets(buf, pt->handle.head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 	if (!buf->snapshot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 		if (pt_buffer_reset_markers(buf, &pt->handle))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 			goto fail_end_stop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 	WRITE_ONCE(pt->handle_nmi, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 	hwc->state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 	pt_config_buffer(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 	pt_config(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) fail_end_stop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 	perf_aux_output_end(&pt->handle, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) fail_stop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 	hwc->state = PERF_HES_STOPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) static void pt_event_stop(struct perf_event *event, int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 	struct pt *pt = this_cpu_ptr(&pt_ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 	 * Protect against the PMI racing with disabling wrmsr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 	 * see comment in intel_pt_interrupt().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 	WRITE_ONCE(pt->handle_nmi, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 	pt_config_stop(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	if (event->hw.state == PERF_HES_STOPPED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 	event->hw.state = PERF_HES_STOPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 	if (mode & PERF_EF_UPDATE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 		struct pt_buffer *buf = perf_get_aux(&pt->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 		if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 		if (WARN_ON_ONCE(pt->handle.event != event))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 		pt_read_offset(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 		pt_handle_status(pt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 		pt_update_head(pt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 		if (buf->snapshot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 			pt->handle.head =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 				local_xchg(&buf->data_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 					   buf->nr_pages << PAGE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 		perf_aux_output_end(&pt->handle, local_xchg(&buf->data_size, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) static long pt_event_snapshot_aux(struct perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 				  struct perf_output_handle *handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 				  unsigned long size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 	struct pt *pt = this_cpu_ptr(&pt_ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 	struct pt_buffer *buf = perf_get_aux(&pt->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 	unsigned long from = 0, to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 	long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 	if (WARN_ON_ONCE(!buf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 	 * Sampling is only allowed on snapshot events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 	 * see pt_buffer_setup_aux().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 	if (WARN_ON_ONCE(!buf->snapshot))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 	 * Here, handle_nmi tells us if the tracing is on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 	if (READ_ONCE(pt->handle_nmi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 		pt_config_stop(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 	pt_read_offset(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 	pt_update_head(pt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 	to = local_read(&buf->data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 	if (to < size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 		from = buf->nr_pages << PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 	from += to - size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 	ret = perf_output_copy_aux(&pt->handle, handle, from, to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 	 * If the tracing was on when we turned up, restart it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 	 * Compiler barrier not needed as we couldn't have been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 	 * preempted by anything that touches pt->handle_nmi.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 	if (pt->handle_nmi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 		pt_config_start(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) static void pt_event_del(struct perf_event *event, int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 	pt_event_stop(event, PERF_EF_UPDATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) static int pt_event_add(struct perf_event *event, int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 	struct pt *pt = this_cpu_ptr(&pt_ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 	struct hw_perf_event *hwc = &event->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 	int ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 	if (pt->handle.event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 	if (mode & PERF_EF_START) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 		pt_event_start(event, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 		if (hwc->state == PERF_HES_STOPPED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 			goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 		hwc->state = PERF_HES_STOPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) static void pt_event_read(struct perf_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) static void pt_event_destroy(struct perf_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 	pt_addr_filters_fini(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 	x86_del_exclusive(x86_lbr_exclusive_pt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) static int pt_event_init(struct perf_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 	if (event->attr.type != pt_pmu.pmu.type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 	if (!pt_event_valid(event))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 	if (x86_add_exclusive(x86_lbr_exclusive_pt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 	if (pt_addr_filters_init(event)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 		x86_del_exclusive(x86_lbr_exclusive_pt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 	event->destroy = pt_event_destroy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) void cpu_emergency_stop_pt(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 	struct pt *pt = this_cpu_ptr(&pt_ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 	if (pt->handle.event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 		pt_event_stop(pt->handle.event, PERF_EF_UPDATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) int is_intel_pt_event(struct perf_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 	return event->pmu == &pt_pmu.pmu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) static __init int pt_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 	int ret, cpu, prior_warn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 	BUILD_BUG_ON(sizeof(struct topa) > PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 	if (!boot_cpu_has(X86_FEATURE_INTEL_PT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 	get_online_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 	for_each_online_cpu(cpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 		u64 ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 		ret = rdmsrl_safe_on_cpu(cpu, MSR_IA32_RTIT_CTL, &ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 		if (!ret && (ctl & RTIT_CTL_TRACEEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 			prior_warn++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 	put_online_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 	if (prior_warn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 		x86_add_exclusive(x86_lbr_exclusive_pt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 		pr_warn("PT is enabled at boot time, doing nothing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 	ret = pt_pmu_hw_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 	if (!intel_pt_validate_hw_cap(PT_CAP_topa_output)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 		pr_warn("ToPA output is not supported on this CPU\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 	if (!intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 		pt_pmu.pmu.capabilities = PERF_PMU_CAP_AUX_NO_SG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 	pt_pmu.pmu.capabilities	|= PERF_PMU_CAP_EXCLUSIVE | PERF_PMU_CAP_ITRACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 	pt_pmu.pmu.attr_groups		 = pt_attr_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 	pt_pmu.pmu.task_ctx_nr		 = perf_sw_context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 	pt_pmu.pmu.event_init		 = pt_event_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 	pt_pmu.pmu.add			 = pt_event_add;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 	pt_pmu.pmu.del			 = pt_event_del;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 	pt_pmu.pmu.start		 = pt_event_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 	pt_pmu.pmu.stop			 = pt_event_stop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 	pt_pmu.pmu.snapshot_aux		 = pt_event_snapshot_aux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 	pt_pmu.pmu.read			 = pt_event_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 	pt_pmu.pmu.setup_aux		 = pt_buffer_setup_aux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 	pt_pmu.pmu.free_aux		 = pt_buffer_free_aux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 	pt_pmu.pmu.addr_filters_sync     = pt_event_addr_filters_sync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 	pt_pmu.pmu.addr_filters_validate = pt_event_addr_filters_validate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 	pt_pmu.pmu.nr_addr_filters       =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 		intel_pt_validate_hw_cap(PT_CAP_num_address_ranges);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 	ret = perf_pmu_register(&pt_pmu.pmu, "intel_pt", -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) arch_initcall(pt_init);