Skip to content

Commit c05e01c

Browse files
Dapeng Migregkh
authored andcommitted
perf/x86/intel: Improve validation and configuration of ACR masks
commit 5ad732a upstream. Currently there are several issues on the user space ACR mask validation and configuration. - The validation for user space ACR mask (attr.config2) is incomplete, e.g., the ACR mask could include the index which belongs to another ACR events group, but it's not validated. - An early return on an invalid ACR mask caused all subsequent ACR groups to be skipped. - The stale hardware ACR mask (hw.config1) is not cleared before setting new hardware ACR mask. The following changes address all of the above issues. - Figure out the event index group of an ACR group. Any bits in the user-space mask not present in the index group are now dropped. - Instead of an early return on invalid bits, drop only the invalid portions and continue iterating through all ACR events to ensure full configuration. - Explicitly clear the stale hardware ACR mask for each event prior to writing the new configuration. Besides, a non-leader event member of ACR group could be disabled in theory. This could cause bit-shifting errors in the acr_mask of remaining group members. But since ACR sampling requires all events to be active, this should not be a big concern in real use case. Add a "FIXME" comment to notice this risk. Fixes: ec980e4 ("perf/x86/intel: Support auto counter reload") Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260430002558.712334-2-dapeng1.mi@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 318bb94 commit c05e01c

1 file changed

Lines changed: 25 additions & 7 deletions

File tree

arch/x86/events/intel/core.c

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3332,23 +3332,41 @@ static void intel_pmu_enable_event(struct perf_event *event)
33323332
static void intel_pmu_acr_late_setup(struct cpu_hw_events *cpuc)
33333333
{
33343334
struct perf_event *event, *leader;
3335-
int i, j, idx;
3335+
int i, j, k, bit, idx;
33363336

3337+
/*
3338+
* FIXME: ACR mask parsing relies on cpuc->event_list[] (active events only).
3339+
* Disabling an ACR event causes bit-shifting errors in the acr_mask of
3340+
* remaining group members. As ACR sampling requires all events to be active,
3341+
* this limitation is acceptable for now. Revisit if independent event toggling
3342+
* is required.
3343+
*/
33373344
for (i = 0; i < cpuc->n_events; i++) {
33383345
leader = cpuc->event_list[i];
33393346
if (!is_acr_event_group(leader))
33403347
continue;
33413348

3342-
/* The ACR events must be contiguous. */
3349+
/* Find the last event of the ACR group. */
33433350
for (j = i; j < cpuc->n_events; j++) {
33443351
event = cpuc->event_list[j];
33453352
if (event->group_leader != leader->group_leader)
33463353
break;
3347-
for_each_set_bit(idx, (unsigned long *)&event->attr.config2, X86_PMC_IDX_MAX) {
3348-
if (i + idx >= cpuc->n_events ||
3349-
!is_acr_event_group(cpuc->event_list[i + idx]))
3350-
return;
3351-
__set_bit(cpuc->assign[i + idx], (unsigned long *)&event->hw.config1);
3354+
}
3355+
3356+
/*
3357+
* Translate the user-space ACR mask (attr.config2) into the physical
3358+
* counter bitmask (hw.config1) for each ACR event in the group.
3359+
* NOTE: ACR event contiguity is guaranteed by intel_pmu_hw_config().
3360+
*/
3361+
for (k = i; k < j; k++) {
3362+
event = cpuc->event_list[k];
3363+
event->hw.config1 = 0;
3364+
for_each_set_bit(bit, (unsigned long *)&event->attr.config2, X86_PMC_IDX_MAX) {
3365+
idx = i + bit;
3366+
/* Event index of ACR group must locate in [i, j). */
3367+
if (idx >= j || !is_acr_event_group(cpuc->event_list[idx]))
3368+
continue;
3369+
__set_bit(cpuc->assign[idx], (unsigned long *)&event->hw.config1);
33523370
}
33533371
}
33543372
i = j - 1;

0 commit comments

Comments
 (0)