提交 37c7ce33 编写于 作者: R Robin Murphy 提交者: Zheng Zengkai

perf/smmuv3: Don't trample existing events with global filter

mainline inclusion
from mainline-v5.13-rc3
commit 4c1daba1
category: bugfix
bugzilla: 175148
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4c1daba15c209b99d192f147fea3dade30f72ed2

------------------------------------------------------------------------

With global filtering, we only allow an event to be scheduled if its
filter settings exactly match those of any existing events, therefore
it is pointless to reapply the filter in that case. Much worse, though,
is that in doing that we trample the event type of counter 0 if it's
already active, and never touch the appropriate PMEVTYPERn so the new
event is likely not counting the right thing either. Don't do that.

CC: stable@vger.kernel.org
Signed-off-by: NRobin Murphy <robin.murphy@arm.com>
Link: https://lore.kernel.org/r/32c80c0e46237f49ad8da0c9f8864e13c4a803aa.1623153312.git.robin.murphy@arm.comSigned-off-by: NWill Deacon <will@kernel.org>
Reviewed-by: NShaokun Zhang <zhangshaokun@hisilicon.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 4135e6e3
......@@ -277,7 +277,7 @@ static int smmu_pmu_apply_event_filter(struct smmu_pmu *smmu_pmu,
struct perf_event *event, int idx)
{
u32 span, sid;
unsigned int num_ctrs = smmu_pmu->num_counters;
unsigned int cur_idx, num_ctrs = smmu_pmu->num_counters;
bool filter_en = !!get_filter_enable(event);
span = filter_en ? get_filter_span(event) :
......@@ -285,17 +285,19 @@ static int smmu_pmu_apply_event_filter(struct smmu_pmu *smmu_pmu,
sid = filter_en ? get_filter_stream_id(event) :
SMMU_PMCG_DEFAULT_FILTER_SID;
/* Support individual filter settings */
if (!smmu_pmu->global_filter) {
cur_idx = find_first_bit(smmu_pmu->used_counters, num_ctrs);
/*
* Per-counter filtering, or scheduling the first globally-filtered
* event into an empty PMU so idx == 0 and it works out equivalent.
*/
if (!smmu_pmu->global_filter || cur_idx == num_ctrs) {
smmu_pmu_set_event_filter(event, idx, span, sid);
return 0;
}
/* Requested settings same as current global settings*/
idx = find_first_bit(smmu_pmu->used_counters, num_ctrs);
if (idx == num_ctrs ||
smmu_pmu_check_global_filter(smmu_pmu->events[idx], event)) {
smmu_pmu_set_event_filter(event, 0, span, sid);
/* Otherwise, must match whatever's currently scheduled */
if (smmu_pmu_check_global_filter(smmu_pmu->events[cur_idx], event)) {
smmu_pmu_set_evtyper(smmu_pmu, idx, get_event(event));
return 0;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册