Skip to content

Commit 3286be9

Browse files
committed
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf fixes from Thomas Gleixner: "A couple of small fixes to x86 perf drivers: - Measure L2 for HW_CACHE* events on AMD - Fix the address filter handling in the intel/pt driver - Handle the BTS disabling at the proper place" * 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: perf/x86/amd: Make HW_CACHE_REFERENCES and HW_CACHE_MISSES measure L2 perf/x86/intel/pt: Do validate the size of a kernel address filter perf/x86/intel/pt: Fix kernel address filter's offset validation perf/x86/intel/pt: Fix an off-by-one in address filter configuration perf/x86/intel: Don't disable "intel_bts" around "intel" event batching
2 parents 6ffa36a + 080fe0b commit 3286be9

File tree

4 files changed

+26
-15
lines changed

4 files changed

+26
-15
lines changed

arch/x86/events/amd/core.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,8 @@ static const u64 amd_perfmon_event_map[PERF_COUNT_HW_MAX] =
119119
{
120120
[PERF_COUNT_HW_CPU_CYCLES] = 0x0076,
121121
[PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0,
122-
[PERF_COUNT_HW_CACHE_REFERENCES] = 0x0080,
123-
[PERF_COUNT_HW_CACHE_MISSES] = 0x0081,
122+
[PERF_COUNT_HW_CACHE_REFERENCES] = 0x077d,
123+
[PERF_COUNT_HW_CACHE_MISSES] = 0x077e,
124124
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c2,
125125
[PERF_COUNT_HW_BRANCH_MISSES] = 0x00c3,
126126
[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x00d0, /* "Decoder empty" event */

arch/x86/events/intel/core.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1730,9 +1730,11 @@ static __initconst const u64 knl_hw_cache_extra_regs
17301730
* disabled state if called consecutively.
17311731
*
17321732
* During consecutive calls, the same disable value will be written to related
1733-
* registers, so the PMU state remains unchanged. hw.state in
1734-
* intel_bts_disable_local will remain PERF_HES_STOPPED too in consecutive
1735-
* calls.
1733+
* registers, so the PMU state remains unchanged.
1734+
*
1735+
* intel_bts events don't coexist with intel PMU's BTS events because of
1736+
* x86_add_exclusive(x86_lbr_exclusive_lbr); there's no need to keep them
1737+
* disabled around intel PMU's event batching etc, only inside the PMI handler.
17361738
*/
17371739
static void __intel_pmu_disable_all(void)
17381740
{
@@ -1742,8 +1744,6 @@ static void __intel_pmu_disable_all(void)
17421744

17431745
if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask))
17441746
intel_pmu_disable_bts();
1745-
else
1746-
intel_bts_disable_local();
17471747

17481748
intel_pmu_pebs_disable_all();
17491749
}
@@ -1771,8 +1771,7 @@ static void __intel_pmu_enable_all(int added, bool pmi)
17711771
return;
17721772

17731773
intel_pmu_enable_bts(event->hw.config);
1774-
} else
1775-
intel_bts_enable_local();
1774+
}
17761775
}
17771776

17781777
static void intel_pmu_enable_all(int added)
@@ -2073,6 +2072,7 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
20732072
*/
20742073
if (!x86_pmu.late_ack)
20752074
apic_write(APIC_LVTPC, APIC_DM_NMI);
2075+
intel_bts_disable_local();
20762076
__intel_pmu_disable_all();
20772077
handled = intel_pmu_drain_bts_buffer();
20782078
handled += intel_bts_interrupt();
@@ -2172,6 +2172,7 @@ static int intel_pmu_handle_irq(struct pt_regs *regs)
21722172
/* Only restore PMU state when it's active. See x86_pmu_disable(). */
21732173
if (cpuc->enabled)
21742174
__intel_pmu_enable_all(0, true);
2175+
intel_bts_enable_local();
21752176

21762177
/*
21772178
* Only unmask the NMI after the overflow counters

arch/x86/events/intel/pt.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,18 +1074,28 @@ static void pt_addr_filters_fini(struct perf_event *event)
10741074
event->hw.addr_filters = NULL;
10751075
}
10761076

1077+
static inline bool valid_kernel_ip(unsigned long ip)
1078+
{
1079+
return virt_addr_valid(ip) && kernel_ip(ip);
1080+
}
1081+
10771082
static int pt_event_addr_filters_validate(struct list_head *filters)
10781083
{
10791084
struct perf_addr_filter *filter;
10801085
int range = 0;
10811086

10821087
list_for_each_entry(filter, filters, entry) {
10831088
/* PT doesn't support single address triggers */
1084-
if (!filter->range)
1089+
if (!filter->range || !filter->size)
10851090
return -EOPNOTSUPP;
10861091

1087-
if (!filter->inode && !kernel_ip(filter->offset))
1088-
return -EINVAL;
1092+
if (!filter->inode) {
1093+
if (!valid_kernel_ip(filter->offset))
1094+
return -EINVAL;
1095+
1096+
if (!valid_kernel_ip(filter->offset + filter->size))
1097+
return -EINVAL;
1098+
}
10891099

10901100
if (++range > pt_cap_get(PT_CAP_num_address_ranges))
10911101
return -EOPNOTSUPP;
@@ -1111,7 +1121,7 @@ static void pt_event_addr_filters_sync(struct perf_event *event)
11111121
} else {
11121122
/* apply the offset */
11131123
msr_a = filter->offset + offs[range];
1114-
msr_b = filter->size + msr_a;
1124+
msr_b = filter->size + msr_a - 1;
11151125
}
11161126

11171127
filters->filter[range].msr_a = msr_a;

arch/x86/kvm/pmu_amd.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
static struct kvm_event_hw_type_mapping amd_event_mapping[] = {
2424
[0] = { 0x76, 0x00, PERF_COUNT_HW_CPU_CYCLES },
2525
[1] = { 0xc0, 0x00, PERF_COUNT_HW_INSTRUCTIONS },
26-
[2] = { 0x80, 0x00, PERF_COUNT_HW_CACHE_REFERENCES },
27-
[3] = { 0x81, 0x00, PERF_COUNT_HW_CACHE_MISSES },
26+
[2] = { 0x7d, 0x07, PERF_COUNT_HW_CACHE_REFERENCES },
27+
[3] = { 0x7e, 0x07, PERF_COUNT_HW_CACHE_MISSES },
2828
[4] = { 0xc2, 0x00, PERF_COUNT_HW_BRANCH_INSTRUCTIONS },
2929
[5] = { 0xc3, 0x00, PERF_COUNT_HW_BRANCH_MISSES },
3030
[6] = { 0xd0, 0x00, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND },

0 commit comments

Comments
 (0)