@@ -86,6 +86,7 @@ struct arm_spe_pmu {
8686#define SPE_PMU_FEAT_ERND (1UL << 5)
8787#define SPE_PMU_FEAT_INV_FILT_EVT (1UL << 6)
8888#define SPE_PMU_FEAT_DISCARD (1UL << 7)
89+ #define SPE_PMU_FEAT_EFT (1UL << 8)
8990#define SPE_PMU_FEAT_DEV_PROBED (1UL << 63)
9091 u64 features ;
9192
@@ -216,6 +217,27 @@ static const struct attribute_group arm_spe_pmu_cap_group = {
216217#define ATTR_CFG_FLD_discard_CFG config /* PMBLIMITR_EL1.FM = DISCARD */
217218#define ATTR_CFG_FLD_discard_LO 35
218219#define ATTR_CFG_FLD_discard_HI 35
220+ #define ATTR_CFG_FLD_branch_filter_mask_CFG config /* PMSFCR_EL1.Bm */
221+ #define ATTR_CFG_FLD_branch_filter_mask_LO 36
222+ #define ATTR_CFG_FLD_branch_filter_mask_HI 36
223+ #define ATTR_CFG_FLD_load_filter_mask_CFG config /* PMSFCR_EL1.LDm */
224+ #define ATTR_CFG_FLD_load_filter_mask_LO 37
225+ #define ATTR_CFG_FLD_load_filter_mask_HI 37
226+ #define ATTR_CFG_FLD_store_filter_mask_CFG config /* PMSFCR_EL1.STm */
227+ #define ATTR_CFG_FLD_store_filter_mask_LO 38
228+ #define ATTR_CFG_FLD_store_filter_mask_HI 38
229+ #define ATTR_CFG_FLD_simd_filter_CFG config /* PMSFCR_EL1.SIMD */
230+ #define ATTR_CFG_FLD_simd_filter_LO 39
231+ #define ATTR_CFG_FLD_simd_filter_HI 39
232+ #define ATTR_CFG_FLD_simd_filter_mask_CFG config /* PMSFCR_EL1.SIMDm */
233+ #define ATTR_CFG_FLD_simd_filter_mask_LO 40
234+ #define ATTR_CFG_FLD_simd_filter_mask_HI 40
235+ #define ATTR_CFG_FLD_float_filter_CFG config /* PMSFCR_EL1.FP */
236+ #define ATTR_CFG_FLD_float_filter_LO 41
237+ #define ATTR_CFG_FLD_float_filter_HI 41
238+ #define ATTR_CFG_FLD_float_filter_mask_CFG config /* PMSFCR_EL1.FPm */
239+ #define ATTR_CFG_FLD_float_filter_mask_LO 42
240+ #define ATTR_CFG_FLD_float_filter_mask_HI 42
219241
220242#define ATTR_CFG_FLD_event_filter_CFG config1 /* PMSEVFR_EL1 */
221243#define ATTR_CFG_FLD_event_filter_LO 0
@@ -234,8 +256,15 @@ GEN_PMU_FORMAT_ATTR(pa_enable);
234256GEN_PMU_FORMAT_ATTR (pct_enable );
235257GEN_PMU_FORMAT_ATTR (jitter );
236258GEN_PMU_FORMAT_ATTR (branch_filter );
259+ GEN_PMU_FORMAT_ATTR (branch_filter_mask );
237260GEN_PMU_FORMAT_ATTR (load_filter );
261+ GEN_PMU_FORMAT_ATTR (load_filter_mask );
238262GEN_PMU_FORMAT_ATTR (store_filter );
263+ GEN_PMU_FORMAT_ATTR (store_filter_mask );
264+ GEN_PMU_FORMAT_ATTR (simd_filter );
265+ GEN_PMU_FORMAT_ATTR (simd_filter_mask );
266+ GEN_PMU_FORMAT_ATTR (float_filter );
267+ GEN_PMU_FORMAT_ATTR (float_filter_mask );
239268GEN_PMU_FORMAT_ATTR (event_filter );
240269GEN_PMU_FORMAT_ATTR (inv_event_filter );
241270GEN_PMU_FORMAT_ATTR (min_latency );
@@ -247,8 +276,15 @@ static struct attribute *arm_spe_pmu_formats_attr[] = {
247276 & format_attr_pct_enable .attr ,
248277 & format_attr_jitter .attr ,
249278 & format_attr_branch_filter .attr ,
279+ & format_attr_branch_filter_mask .attr ,
250280 & format_attr_load_filter .attr ,
281+ & format_attr_load_filter_mask .attr ,
251282 & format_attr_store_filter .attr ,
283+ & format_attr_store_filter_mask .attr ,
284+ & format_attr_simd_filter .attr ,
285+ & format_attr_simd_filter_mask .attr ,
286+ & format_attr_float_filter .attr ,
287+ & format_attr_float_filter_mask .attr ,
252288 & format_attr_event_filter .attr ,
253289 & format_attr_inv_event_filter .attr ,
254290 & format_attr_min_latency .attr ,
@@ -269,6 +305,16 @@ static umode_t arm_spe_pmu_format_attr_is_visible(struct kobject *kobj,
269305 if (attr == & format_attr_inv_event_filter .attr && !(spe_pmu -> features & SPE_PMU_FEAT_INV_FILT_EVT ))
270306 return 0 ;
271307
308+ if ((attr == & format_attr_branch_filter_mask .attr ||
309+ attr == & format_attr_load_filter_mask .attr ||
310+ attr == & format_attr_store_filter_mask .attr ||
311+ attr == & format_attr_simd_filter .attr ||
312+ attr == & format_attr_simd_filter_mask .attr ||
313+ attr == & format_attr_float_filter .attr ||
314+ attr == & format_attr_float_filter_mask .attr ) &&
315+ !(spe_pmu -> features & SPE_PMU_FEAT_EFT ))
316+ return 0 ;
317+
272318 return attr -> mode ;
273319}
274320
@@ -364,8 +410,15 @@ static u64 arm_spe_event_to_pmsfcr(struct perf_event *event)
364410 u64 reg = 0 ;
365411
366412 reg |= FIELD_PREP (PMSFCR_EL1_LD , ATTR_CFG_GET_FLD (attr , load_filter ));
413+ reg |= FIELD_PREP (PMSFCR_EL1_LDm , ATTR_CFG_GET_FLD (attr , load_filter_mask ));
367414 reg |= FIELD_PREP (PMSFCR_EL1_ST , ATTR_CFG_GET_FLD (attr , store_filter ));
415+ reg |= FIELD_PREP (PMSFCR_EL1_STm , ATTR_CFG_GET_FLD (attr , store_filter_mask ));
368416 reg |= FIELD_PREP (PMSFCR_EL1_B , ATTR_CFG_GET_FLD (attr , branch_filter ));
417+ reg |= FIELD_PREP (PMSFCR_EL1_Bm , ATTR_CFG_GET_FLD (attr , branch_filter_mask ));
418+ reg |= FIELD_PREP (PMSFCR_EL1_SIMD , ATTR_CFG_GET_FLD (attr , simd_filter ));
419+ reg |= FIELD_PREP (PMSFCR_EL1_SIMDm , ATTR_CFG_GET_FLD (attr , simd_filter_mask ));
420+ reg |= FIELD_PREP (PMSFCR_EL1_FP , ATTR_CFG_GET_FLD (attr , float_filter ));
421+ reg |= FIELD_PREP (PMSFCR_EL1_FPm , ATTR_CFG_GET_FLD (attr , float_filter_mask ));
369422
370423 if (reg )
371424 reg |= PMSFCR_EL1_FT ;
@@ -767,6 +820,16 @@ static int arm_spe_pmu_event_init(struct perf_event *event)
767820 !(spe_pmu -> features & SPE_PMU_FEAT_FILT_LAT ))
768821 return - EOPNOTSUPP ;
769822
823+ if ((FIELD_GET (PMSFCR_EL1_LDm , reg ) ||
824+ FIELD_GET (PMSFCR_EL1_STm , reg ) ||
825+ FIELD_GET (PMSFCR_EL1_Bm , reg ) ||
826+ FIELD_GET (PMSFCR_EL1_SIMD , reg ) ||
827+ FIELD_GET (PMSFCR_EL1_SIMDm , reg ) ||
828+ FIELD_GET (PMSFCR_EL1_FP , reg ) ||
829+ FIELD_GET (PMSFCR_EL1_FPm , reg )) &&
830+ !(spe_pmu -> features & SPE_PMU_FEAT_EFT ))
831+ return - EOPNOTSUPP ;
832+
770833 if (ATTR_CFG_GET_FLD (& event -> attr , discard ) &&
771834 !(spe_pmu -> features & SPE_PMU_FEAT_DISCARD ))
772835 return - EOPNOTSUPP ;
@@ -1058,6 +1121,9 @@ static void __arm_spe_pmu_dev_probe(void *info)
10581121 if (spe_pmu -> pmsver >= ID_AA64DFR0_EL1_PMSVer_V1P2 )
10591122 spe_pmu -> features |= SPE_PMU_FEAT_DISCARD ;
10601123
1124+ if (FIELD_GET (PMSIDR_EL1_EFT , reg ))
1125+ spe_pmu -> features |= SPE_PMU_FEAT_EFT ;
1126+
10611127 /* This field has a spaced out encoding, so just use a look-up */
10621128 fld = FIELD_GET (PMSIDR_EL1_INTERVAL , reg );
10631129 switch (fld ) {
0 commit comments