Skip to content

Commit b440140

Browse files
james-c-linarowilldeacon
authored andcommitted
perf: arm_spe: Support FEAT_SPEv1p4 filters
FEAT_SPEv1p4 (optional from Armv8.8) adds some new filter bits and also makes some previously available bits unavailable again e.g: E[30], bit [30] When FEAT_SPEv1p4 is _not_ implemented ... Continuing to hard code the valid filter bits for each version isn't scalable, and it also doesn't work for filter bits that aren't related to SPE version. For example most bits have a further condition: E[15], bit [15] When ... and filtering on event 15 is supported: Whether "filtering on event 15" is implemented or not is only discoverable from the TRM of that specific CPU or by probing PMSEVFR_EL1. Instead of hard coding them, write all 1s to the PMSEVFR_EL1 register and read it back to discover the RES0 bits. Unsupported bits are RAZ/WI so should read as 0s. For any hardware that doesn't strictly follow RAZ/WI for unsupported filters: Any bits that should have been supported in a specific SPE version but now incorrectly appear to be RES0 wouldn't have worked anyway, so it's better to fail to open events that request them rather than behaving unexpectedly. Bits that aren't implemented but also aren't RAZ/WI will be incorrectly reported as supported, but allowing them to be used is harmless. Testing on N1SDP shows the probed RES0 bits to be the same as the hard coded ones. The FVP with SPEv1p4 shows only additional new RES0 bits, i.e. no previously hard coded RES0 bits are missing. Tested-by: Leo Yan <[email protected]> Signed-off-by: James Clark <[email protected]> Signed-off-by: Will Deacon <[email protected]>
1 parent a7005ff commit b440140

File tree

2 files changed

+7
-25
lines changed

2 files changed

+7
-25
lines changed

arch/arm64/include/asm/sysreg.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -344,15 +344,6 @@
344344
#define SYS_PAR_EL1_ATTR GENMASK_ULL(63, 56)
345345
#define SYS_PAR_EL1_F0_RES0 (GENMASK_ULL(6, 1) | GENMASK_ULL(55, 52))
346346

347-
/*** Statistical Profiling Extension ***/
348-
#define PMSEVFR_EL1_RES0_IMP \
349-
(GENMASK_ULL(47, 32) | GENMASK_ULL(23, 16) | GENMASK_ULL(11, 8) |\
350-
BIT_ULL(6) | BIT_ULL(4) | BIT_ULL(2) | BIT_ULL(0))
351-
#define PMSEVFR_EL1_RES0_V1P1 \
352-
(PMSEVFR_EL1_RES0_IMP & ~(BIT_ULL(18) | BIT_ULL(17) | BIT_ULL(11)))
353-
#define PMSEVFR_EL1_RES0_V1P2 \
354-
(PMSEVFR_EL1_RES0_V1P1 & ~BIT_ULL(6))
355-
356347
/* Buffer error reporting */
357348
#define PMBSR_EL1_FAULT_FSC_SHIFT PMBSR_EL1_MSS_SHIFT
358349
#define PMBSR_EL1_FAULT_FSC_MASK PMBSR_EL1_MSS_MASK

drivers/perf/arm_spe_pmu.c

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ struct arm_spe_pmu {
8989
#define SPE_PMU_FEAT_DEV_PROBED (1UL << 63)
9090
u64 features;
9191

92+
u64 pmsevfr_res0;
9293
u16 max_record_sz;
9394
u16 align;
9495
struct perf_output_handle __percpu *handle;
@@ -697,20 +698,6 @@ static irqreturn_t arm_spe_pmu_irq_handler(int irq, void *dev)
697698
return IRQ_HANDLED;
698699
}
699700

700-
static u64 arm_spe_pmsevfr_res0(u16 pmsver)
701-
{
702-
switch (pmsver) {
703-
case ID_AA64DFR0_EL1_PMSVer_IMP:
704-
return PMSEVFR_EL1_RES0_IMP;
705-
case ID_AA64DFR0_EL1_PMSVer_V1P1:
706-
return PMSEVFR_EL1_RES0_V1P1;
707-
case ID_AA64DFR0_EL1_PMSVer_V1P2:
708-
/* Return the highest version we support in default */
709-
default:
710-
return PMSEVFR_EL1_RES0_V1P2;
711-
}
712-
}
713-
714701
/* Perf callbacks */
715702
static int arm_spe_pmu_event_init(struct perf_event *event)
716703
{
@@ -726,10 +713,10 @@ static int arm_spe_pmu_event_init(struct perf_event *event)
726713
!cpumask_test_cpu(event->cpu, &spe_pmu->supported_cpus))
727714
return -ENOENT;
728715

729-
if (arm_spe_event_to_pmsevfr(event) & arm_spe_pmsevfr_res0(spe_pmu->pmsver))
716+
if (arm_spe_event_to_pmsevfr(event) & spe_pmu->pmsevfr_res0)
730717
return -EOPNOTSUPP;
731718

732-
if (arm_spe_event_to_pmsnevfr(event) & arm_spe_pmsevfr_res0(spe_pmu->pmsver))
719+
if (arm_spe_event_to_pmsnevfr(event) & spe_pmu->pmsevfr_res0)
733720
return -EOPNOTSUPP;
734721

735722
if (attr->exclude_idle)
@@ -1107,6 +1094,10 @@ static void __arm_spe_pmu_dev_probe(void *info)
11071094
spe_pmu->counter_sz = 16;
11081095
}
11091096

1097+
/* Write all 1s and then read back. Unsupported filter bits are RAZ/WI. */
1098+
write_sysreg_s(U64_MAX, SYS_PMSEVFR_EL1);
1099+
spe_pmu->pmsevfr_res0 = ~read_sysreg_s(SYS_PMSEVFR_EL1);
1100+
11101101
dev_info(dev,
11111102
"probed SPEv1.%d for CPUs %*pbl [max_record_sz %u, align %u, features 0x%llx]\n",
11121103
spe_pmu->pmsver - 1, cpumask_pr_args(&spe_pmu->supported_cpus),

0 commit comments

Comments
 (0)