Commit 95ab0e87 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'perf-core-2022-03-21' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 perf event updates from Ingo Molnar:

 - Fix address filtering for Intel/PT,ARM/CoreSight

 - Enable Intel/PEBS format 5

 - Allow more fixed-function counters for x86

 - Intel/PT: Enable not recording Taken-Not-Taken packets

 - Add a few branch-types

* tag 'perf-core-2022-03-21' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  perf/x86/intel/uncore: Fix the build on !CONFIG_PHYS_ADDR_T_64BIT
  perf: Add irq and exception return branch types
  perf/x86/intel/uncore: Make uncore_discovery clean for 64 bit addresses
  perf/x86/intel/pt: Add a capability and config bit for disabling TNTs
  perf/x86/intel/pt: Add a capability and config bit for event tracing
  perf/x86/intel: Increase max number of the fixed counters
  KVM: x86: use the KVM side max supported fixed counter
  perf/x86/intel: Enable PEBS format 5
  perf/core: Allow kernel address filter when not filtering the kernel
  perf/x86/intel/pt: Fix address filter config for 32-bit kernel
  perf/core: Fix address filter parser for multiple filters
  x86: Share definition of __is_canonical_address()
  perf/x86/intel/pt: Relax address filter validation
parents 51912904 02a08d78
Loading
Loading
Loading
Loading
+39 −1
Original line number Diff line number Diff line
@@ -181,6 +181,27 @@ static struct event_constraint intel_gen_event_constraints[] __read_mostly =
	EVENT_CONSTRAINT_END
};

static struct event_constraint intel_v5_gen_event_constraints[] __read_mostly =
{
	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
	FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
	FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */
	FIXED_EVENT_CONSTRAINT(0x0400, 3), /* SLOTS */
	FIXED_EVENT_CONSTRAINT(0x0500, 4),
	FIXED_EVENT_CONSTRAINT(0x0600, 5),
	FIXED_EVENT_CONSTRAINT(0x0700, 6),
	FIXED_EVENT_CONSTRAINT(0x0800, 7),
	FIXED_EVENT_CONSTRAINT(0x0900, 8),
	FIXED_EVENT_CONSTRAINT(0x0a00, 9),
	FIXED_EVENT_CONSTRAINT(0x0b00, 10),
	FIXED_EVENT_CONSTRAINT(0x0c00, 11),
	FIXED_EVENT_CONSTRAINT(0x0d00, 12),
	FIXED_EVENT_CONSTRAINT(0x0e00, 13),
	FIXED_EVENT_CONSTRAINT(0x0f00, 14),
	FIXED_EVENT_CONSTRAINT(0x1000, 15),
	EVENT_CONSTRAINT_END
};

static struct event_constraint intel_slm_event_constraints[] __read_mostly =
{
	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
@@ -6308,7 +6329,9 @@ __init int intel_pmu_init(void)
			pr_cont("generic architected perfmon v1, ");
			name = "generic_arch_v1";
			break;
		default:
		case 2:
		case 3:
		case 4:
			/*
			 * default constraints for v2 and up
			 */
@@ -6316,6 +6339,21 @@ __init int intel_pmu_init(void)
			pr_cont("generic architected perfmon, ");
			name = "generic_arch_v2+";
			break;
		default:
			/*
			 * The default constraints for v5 and up can support up to
			 * 16 fixed counters. For the fixed counters 4 and later,
			 * the pseudo-encoding is applied.
			 * The constraints may be cut according to the CPUID enumeration
			 * by inserting the EVENT_CONSTRAINT_END.
			 */
			if (x86_pmu.num_counters_fixed > INTEL_PMC_MAX_FIXED)
				x86_pmu.num_counters_fixed = INTEL_PMC_MAX_FIXED;
			intel_v5_gen_event_constraints[x86_pmu.num_counters_fixed].weight = -1;
			x86_pmu.event_constraints = intel_v5_gen_event_constraints;
			pr_cont("generic architected perfmon, ");
			name = "generic_arch_v5+";
			break;
		}
	}

+11 −3
Original line number Diff line number Diff line
@@ -1203,6 +1203,9 @@ static void intel_pmu_pebs_via_pt_enable(struct perf_event *event)
	if (hwc->idx >= INTEL_PMC_IDX_FIXED) {
		base = MSR_RELOAD_FIXED_CTR0;
		idx = hwc->idx - INTEL_PMC_IDX_FIXED;
		if (x86_pmu.intel_cap.pebs_format < 5)
			value = ds->pebs_event_reset[MAX_PEBS_EVENTS_FMT4 + idx];
		else
			value = ds->pebs_event_reset[MAX_PEBS_EVENTS + idx];
	}
	wrmsrl(base + idx, value);
@@ -1232,8 +1235,12 @@ void intel_pmu_pebs_enable(struct perf_event *event)
		}
	}

	if (idx >= INTEL_PMC_IDX_FIXED)
	if (idx >= INTEL_PMC_IDX_FIXED) {
		if (x86_pmu.intel_cap.pebs_format < 5)
			idx = MAX_PEBS_EVENTS_FMT4 + (idx - INTEL_PMC_IDX_FIXED);
		else
			idx = MAX_PEBS_EVENTS + (idx - INTEL_PMC_IDX_FIXED);
	}

	/*
	 * Use auto-reload if possible to save a MSR write in the PMI.
@@ -2204,6 +2211,7 @@ void __init intel_ds_init(void)
			break;

		case 4:
		case 5:
			x86_pmu.drain_pebs = intel_pmu_drain_pebs_icl;
			x86_pmu.pebs_record_size = sizeof(struct pebs_basic);
			if (x86_pmu.intel_cap.pebs_baseline) {
+2 −2
Original line number Diff line number Diff line
@@ -1329,10 +1329,10 @@ static int branch_map[X86_BR_TYPE_MAP_MAX] = {
	PERF_BR_SYSCALL,	/* X86_BR_SYSCALL */
	PERF_BR_SYSRET,		/* X86_BR_SYSRET */
	PERF_BR_UNKNOWN,	/* X86_BR_INT */
	PERF_BR_UNKNOWN,	/* X86_BR_IRET */
	PERF_BR_ERET,		/* X86_BR_IRET */
	PERF_BR_COND,		/* X86_BR_JCC */
	PERF_BR_UNCOND,		/* X86_BR_JMP */
	PERF_BR_UNKNOWN,	/* X86_BR_IRQ */
	PERF_BR_IRQ,		/* X86_BR_IRQ */
	PERF_BR_IND_CALL,	/* X86_BR_IND_CALL */
	PERF_BR_UNKNOWN,	/* X86_BR_ABORT */
	PERF_BR_UNKNOWN,	/* X86_BR_IN_TX */
+57 −14
Original line number Diff line number Diff line
@@ -13,6 +13,8 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/types.h>
#include <linux/bits.h>
#include <linux/limits.h>
#include <linux/slab.h>
#include <linux/device.h>

@@ -57,6 +59,8 @@ static struct pt_cap_desc {
	PT_CAP(mtc,			0, CPUID_EBX, BIT(3)),
	PT_CAP(ptwrite,			0, CPUID_EBX, BIT(4)),
	PT_CAP(power_event_trace,	0, CPUID_EBX, BIT(5)),
	PT_CAP(event_trace,		0, CPUID_EBX, BIT(7)),
	PT_CAP(tnt_disable,		0, CPUID_EBX, BIT(8)),
	PT_CAP(topa_output,		0, CPUID_ECX, BIT(0)),
	PT_CAP(topa_multiple_entries,	0, CPUID_ECX, BIT(1)),
	PT_CAP(single_range_output,	0, CPUID_ECX, BIT(2)),
@@ -108,6 +112,8 @@ PMU_FORMAT_ATTR(tsc, "config:10" );
PMU_FORMAT_ATTR(noretcomp,	"config:11"	);
PMU_FORMAT_ATTR(ptw,		"config:12"	);
PMU_FORMAT_ATTR(branch,		"config:13"	);
PMU_FORMAT_ATTR(event,		"config:31"	);
PMU_FORMAT_ATTR(notnt,		"config:55"	);
PMU_FORMAT_ATTR(mtc_period,	"config:14-17"	);
PMU_FORMAT_ATTR(cyc_thresh,	"config:19-22"	);
PMU_FORMAT_ATTR(psb_period,	"config:24-27"	);
@@ -116,6 +122,8 @@ static struct attribute *pt_formats_attr[] = {
	&format_attr_pt.attr,
	&format_attr_cyc.attr,
	&format_attr_pwr_evt.attr,
	&format_attr_event.attr,
	&format_attr_notnt.attr,
	&format_attr_fup_on_ptw.attr,
	&format_attr_mtc.attr,
	&format_attr_tsc.attr,
@@ -296,6 +304,8 @@ static int __init pt_pmu_hw_init(void)
			RTIT_CTL_CYC_PSB	| \
			RTIT_CTL_MTC		| \
			RTIT_CTL_PWR_EVT_EN	| \
			RTIT_CTL_EVENT_EN	| \
			RTIT_CTL_NOTNT		| \
			RTIT_CTL_FUP_ON_PTW	| \
			RTIT_CTL_PTW_EN)

@@ -350,6 +360,14 @@ static bool pt_event_valid(struct perf_event *event)
	    !intel_pt_validate_hw_cap(PT_CAP_power_event_trace))
		return false;

	if (config & RTIT_CTL_EVENT_EN &&
	    !intel_pt_validate_hw_cap(PT_CAP_event_trace))
		return false;

	if (config & RTIT_CTL_NOTNT &&
	    !intel_pt_validate_hw_cap(PT_CAP_tnt_disable))
		return false;

	if (config & RTIT_CTL_PTW) {
		if (!intel_pt_validate_hw_cap(PT_CAP_ptwrite))
			return false;
@@ -472,7 +490,7 @@ static u64 pt_config_filters(struct perf_event *event)
			pt->filters.filter[range].msr_b = filter->msr_b;
		}

		rtit_ctl |= filter->config << pt_address_ranges[range].reg_off;
		rtit_ctl |= (u64)filter->config << pt_address_ranges[range].reg_off;
	}

	return rtit_ctl;
@@ -1348,11 +1366,27 @@ static void pt_addr_filters_fini(struct perf_event *event)
	event->hw.addr_filters = NULL;
}

static inline bool valid_kernel_ip(unsigned long ip)
#ifdef CONFIG_X86_64
/* Clamp to a canonical address greater-than-or-equal-to the address given */
static u64 clamp_to_ge_canonical_addr(u64 vaddr, u8 vaddr_bits)
{
	return virt_addr_valid(ip) && kernel_ip(ip);
	return __is_canonical_address(vaddr, vaddr_bits) ?
	       vaddr :
	       -BIT_ULL(vaddr_bits - 1);
}

/* Clamp to a canonical address less-than-or-equal-to the address given */
static u64 clamp_to_le_canonical_addr(u64 vaddr, u8 vaddr_bits)
{
	return __is_canonical_address(vaddr, vaddr_bits) ?
	       vaddr :
	       BIT_ULL(vaddr_bits - 1) - 1;
}
#else
#define clamp_to_ge_canonical_addr(x, y) (x)
#define clamp_to_le_canonical_addr(x, y) (x)
#endif

static int pt_event_addr_filters_validate(struct list_head *filters)
{
	struct perf_addr_filter *filter;
@@ -1367,14 +1401,6 @@ static int pt_event_addr_filters_validate(struct list_head *filters)
		    filter->action == PERF_ADDR_FILTER_ACTION_START)
			return -EOPNOTSUPP;

		if (!filter->path.dentry) {
			if (!valid_kernel_ip(filter->offset))
				return -EINVAL;

			if (!valid_kernel_ip(filter->offset + filter->size))
				return -EINVAL;
		}

		if (++range > intel_pt_validate_hw_cap(PT_CAP_num_address_ranges))
			return -EOPNOTSUPP;
	}
@@ -1398,9 +1424,26 @@ static void pt_event_addr_filters_sync(struct perf_event *event)
		if (filter->path.dentry && !fr[range].start) {
			msr_a = msr_b = 0;
		} else {
			/* apply the offset */
			msr_a = fr[range].start;
			msr_b = msr_a + fr[range].size - 1;
			unsigned long n = fr[range].size - 1;
			unsigned long a = fr[range].start;
			unsigned long b;

			if (a > ULONG_MAX - n)
				b = ULONG_MAX;
			else
				b = a + n;
			/*
			 * Apply the offset. 64-bit addresses written to the
			 * MSRs must be canonical, but the range can encompass
			 * non-canonical addresses. Since software cannot
			 * execute at non-canonical addresses, adjusting to
			 * canonical addresses does not affect the result of the
			 * address filter.
			 */
			msr_a = clamp_to_ge_canonical_addr(a, boot_cpu_data.x86_virt_bits);
			msr_b = clamp_to_le_canonical_addr(b, boot_cpu_data.x86_virt_bits);
			if (msr_b < msr_a)
				msr_a = msr_b = 0;
		}

		filters->filter[range].msr_a  = msr_a;
+12 −4
Original line number Diff line number Diff line
@@ -215,10 +215,18 @@ static int parse_discovery_table(struct pci_dev *dev, int die,

	pci_read_config_dword(dev, bar_offset, &val);

	if (val & UNCORE_DISCOVERY_MASK)
	if (val & ~PCI_BASE_ADDRESS_MEM_MASK & ~PCI_BASE_ADDRESS_MEM_TYPE_64)
		return -EINVAL;

	addr = (resource_size_t)(val & ~UNCORE_DISCOVERY_MASK);
	addr = (resource_size_t)(val & PCI_BASE_ADDRESS_MEM_MASK);
#ifdef CONFIG_PHYS_ADDR_T_64BIT
	if ((val & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64) {
		u32 val2;

		pci_read_config_dword(dev, bar_offset + 4, &val2);
		addr |= ((resource_size_t)val2) << 32;
	}
#endif
	size = UNCORE_DISCOVERY_GLOBAL_MAP_SIZE;
	io_addr = ioremap(addr, size);
	if (!io_addr)
@@ -444,7 +452,7 @@ static struct intel_uncore_ops generic_uncore_pci_ops = {

#define UNCORE_GENERIC_MMIO_SIZE		0x4000

static unsigned int generic_uncore_mmio_box_ctl(struct intel_uncore_box *box)
static u64 generic_uncore_mmio_box_ctl(struct intel_uncore_box *box)
{
	struct intel_uncore_type *type = box->pmu->type;

@@ -456,7 +464,7 @@ static unsigned int generic_uncore_mmio_box_ctl(struct intel_uncore_box *box)

void intel_generic_uncore_mmio_init_box(struct intel_uncore_box *box)
{
	unsigned int box_ctl = generic_uncore_mmio_box_ctl(box);
	u64 box_ctl = generic_uncore_mmio_box_ctl(box);
	struct intel_uncore_type *type = box->pmu->type;
	resource_size_t addr;

Loading