mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-27 03:10:12 +00:00
perf/x86/intel/pt: Add new timing packet enables
Intel PT chapter in the new Intel Architecture SDM adds several packets corresponding enable bits and registers that control packet generation. Also, additional bits in the Intel PT CPUID leaf were added to enumerate presence and parameters of these new packets and features. The packets and enables are: * CYC: cycle accurate mode, provides the number of cycles elapsed since previous CYC packet; its presence and available threshold values are enumerated via CPUID; * MTC: mini time counter packets, used for tracking TSC time between full TSC packets; its presence and available resolution options are enumerated via CPUID; * PSB packet period is now configurable, available period values are enumerated via CPUID. This patch adds corresponding bit and register definitions, pmu driver capabilities based on CPUID enumeration, new attribute format bits for the new featurens and extends event configuration validation function to take these into account. Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: acme@infradead.org Cc: adrian.hunter@intel.com Cc: hpa@zytor.com Link: http://lkml.kernel.org/r/1438262131-12725-1-git-send-email-alexander.shishkin@linux.intel.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
parent
9a6694cfa2
commit
b1bf72d669
3 changed files with 81 additions and 1 deletions
|
@ -80,13 +80,21 @@
|
|||
|
||||
#define MSR_IA32_RTIT_CTL 0x00000570
|
||||
#define RTIT_CTL_TRACEEN BIT(0)
|
||||
#define RTIT_CTL_CYCLEACC BIT(1)
|
||||
#define RTIT_CTL_OS BIT(2)
|
||||
#define RTIT_CTL_USR BIT(3)
|
||||
#define RTIT_CTL_CR3EN BIT(7)
|
||||
#define RTIT_CTL_TOPA BIT(8)
|
||||
#define RTIT_CTL_MTC_EN BIT(9)
|
||||
#define RTIT_CTL_TSC_EN BIT(10)
|
||||
#define RTIT_CTL_DISRETC BIT(11)
|
||||
#define RTIT_CTL_BRANCH_EN BIT(13)
|
||||
#define RTIT_CTL_MTC_RANGE_OFFSET 14
|
||||
#define RTIT_CTL_MTC_RANGE (0x0full << RTIT_CTL_MTC_RANGE_OFFSET)
|
||||
#define RTIT_CTL_CYC_THRESH_OFFSET 19
|
||||
#define RTIT_CTL_CYC_THRESH (0x0full << RTIT_CTL_CYC_THRESH_OFFSET)
|
||||
#define RTIT_CTL_PSB_FREQ_OFFSET 24
|
||||
#define RTIT_CTL_PSB_FREQ (0x0full << RTIT_CTL_PSB_FREQ_OFFSET)
|
||||
#define MSR_IA32_RTIT_STATUS 0x00000571
|
||||
#define RTIT_STATUS_CONTEXTEN BIT(1)
|
||||
#define RTIT_STATUS_TRIGGEREN BIT(2)
|
||||
|
|
|
@ -72,9 +72,15 @@ struct topa_entry {
|
|||
enum pt_capabilities {
|
||||
PT_CAP_max_subleaf = 0,
|
||||
PT_CAP_cr3_filtering,
|
||||
PT_CAP_psb_cyc,
|
||||
PT_CAP_mtc,
|
||||
PT_CAP_topa_output,
|
||||
PT_CAP_topa_multiple_entries,
|
||||
PT_CAP_single_range_output,
|
||||
PT_CAP_payloads_lip,
|
||||
PT_CAP_mtc_periods,
|
||||
PT_CAP_cycle_thresholds,
|
||||
PT_CAP_psb_periods,
|
||||
};
|
||||
|
||||
struct pt_pmu {
|
||||
|
|
|
@ -65,9 +65,15 @@ static struct pt_cap_desc {
|
|||
} pt_caps[] = {
|
||||
PT_CAP(max_subleaf, 0, CR_EAX, 0xffffffff),
|
||||
PT_CAP(cr3_filtering, 0, CR_EBX, BIT(0)),
|
||||
PT_CAP(psb_cyc, 0, CR_EBX, BIT(1)),
|
||||
PT_CAP(mtc, 0, CR_EBX, BIT(3)),
|
||||
PT_CAP(topa_output, 0, CR_ECX, BIT(0)),
|
||||
PT_CAP(topa_multiple_entries, 0, CR_ECX, BIT(1)),
|
||||
PT_CAP(single_range_output, 0, CR_ECX, BIT(2)),
|
||||
PT_CAP(payloads_lip, 0, CR_ECX, BIT(31)),
|
||||
PT_CAP(mtc_periods, 1, CR_EAX, 0xffff0000),
|
||||
PT_CAP(cycle_thresholds, 1, CR_EBX, 0xffff),
|
||||
PT_CAP(psb_periods, 1, CR_EBX, 0xffff0000),
|
||||
};
|
||||
|
||||
static u32 pt_cap_get(enum pt_capabilities cap)
|
||||
|
@ -94,12 +100,22 @@ static struct attribute_group pt_cap_group = {
|
|||
.name = "caps",
|
||||
};
|
||||
|
||||
PMU_FORMAT_ATTR(cyc, "config:1" );
|
||||
PMU_FORMAT_ATTR(mtc, "config:9" );
|
||||
PMU_FORMAT_ATTR(tsc, "config:10" );
|
||||
PMU_FORMAT_ATTR(noretcomp, "config:11" );
|
||||
PMU_FORMAT_ATTR(mtc_period, "config:14-17" );
|
||||
PMU_FORMAT_ATTR(cyc_thresh, "config:19-22" );
|
||||
PMU_FORMAT_ATTR(psb_period, "config:24-27" );
|
||||
|
||||
static struct attribute *pt_formats_attr[] = {
|
||||
&format_attr_cyc.attr,
|
||||
&format_attr_mtc.attr,
|
||||
&format_attr_tsc.attr,
|
||||
&format_attr_noretcomp.attr,
|
||||
&format_attr_mtc_period.attr,
|
||||
&format_attr_cyc_thresh.attr,
|
||||
&format_attr_psb_period.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -170,15 +186,65 @@ static int __init pt_pmu_hw_init(void)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#define PT_CONFIG_MASK (RTIT_CTL_TSC_EN | RTIT_CTL_DISRETC)
|
||||
#define RTIT_CTL_CYC_PSB (RTIT_CTL_CYCLEACC | \
|
||||
RTIT_CTL_CYC_THRESH | \
|
||||
RTIT_CTL_PSB_FREQ)
|
||||
|
||||
#define RTIT_CTL_MTC (RTIT_CTL_MTC_EN | \
|
||||
RTIT_CTL_MTC_RANGE)
|
||||
|
||||
#define PT_CONFIG_MASK (RTIT_CTL_TSC_EN | \
|
||||
RTIT_CTL_DISRETC | \
|
||||
RTIT_CTL_CYC_PSB | \
|
||||
RTIT_CTL_MTC)
|
||||
|
||||
static bool pt_event_valid(struct perf_event *event)
|
||||
{
|
||||
u64 config = event->attr.config;
|
||||
u64 allowed, requested;
|
||||
|
||||
if ((config & PT_CONFIG_MASK) != config)
|
||||
return false;
|
||||
|
||||
if (config & RTIT_CTL_CYC_PSB) {
|
||||
if (!pt_cap_get(PT_CAP_psb_cyc))
|
||||
return false;
|
||||
|
||||
allowed = pt_cap_get(PT_CAP_psb_periods);
|
||||
requested = (config & RTIT_CTL_PSB_FREQ) >>
|
||||
RTIT_CTL_PSB_FREQ_OFFSET;
|
||||
if (requested && (!(allowed & BIT(requested))))
|
||||
return false;
|
||||
|
||||
allowed = pt_cap_get(PT_CAP_cycle_thresholds);
|
||||
requested = (config & RTIT_CTL_CYC_THRESH) >>
|
||||
RTIT_CTL_CYC_THRESH_OFFSET;
|
||||
if (requested && (!(allowed & BIT(requested))))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (config & RTIT_CTL_MTC) {
|
||||
/*
|
||||
* In the unlikely case that CPUID lists valid mtc periods,
|
||||
* but not the mtc capability, drop out here.
|
||||
*
|
||||
* Spec says that setting mtc period bits while mtc bit in
|
||||
* CPUID is 0 will #GP, so better safe than sorry.
|
||||
*/
|
||||
if (!pt_cap_get(PT_CAP_mtc))
|
||||
return false;
|
||||
|
||||
allowed = pt_cap_get(PT_CAP_mtc_periods);
|
||||
if (!allowed)
|
||||
return false;
|
||||
|
||||
requested = (config & RTIT_CTL_MTC_RANGE) >>
|
||||
RTIT_CTL_MTC_RANGE_OFFSET;
|
||||
|
||||
if (!(allowed & BIT(requested)))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue