Skip to content

Commit 880fcc3

Browse files
atishp04avpatel
authored andcommitted
drivers/perf: riscv: Export PMU event info function
The event mapping function can be used in event info function to find out the corresponding SBI PMU event encoding during the get_event_info function as well. Refactor and export it so that it can be invoked from kvm and internal driver. Signed-off-by: Atish Patra <[email protected]> Reviewed-by: Anup Patel <[email protected]> Acked-by: Paul Walmsley <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Anup Patel <[email protected]>
1 parent adffbd0 commit 880fcc3

2 files changed

Lines changed: 68 additions & 55 deletions

File tree

drivers/perf/riscv_pmu_sbi.c

Lines changed: 67 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ static unsigned int riscv_pmu_irq;
100100
/* Cache the available counters in a bitmask */
101101
static unsigned long cmask;
102102

103+
static int pmu_event_find_cache(u64 config);
103104
struct sbi_pmu_event_data {
104105
union {
105106
union {
@@ -412,6 +413,71 @@ static bool pmu_sbi_ctr_is_fw(int cidx)
412413
return (info->type == SBI_PMU_CTR_TYPE_FW) ? true : false;
413414
}
414415

416+
int riscv_pmu_get_event_info(u32 type, u64 config, u64 *econfig)
417+
{
418+
int ret = -ENOENT;
419+
420+
switch (type) {
421+
case PERF_TYPE_HARDWARE:
422+
if (config >= PERF_COUNT_HW_MAX)
423+
return -EINVAL;
424+
ret = pmu_hw_event_map[config].event_idx;
425+
break;
426+
case PERF_TYPE_HW_CACHE:
427+
ret = pmu_event_find_cache(config);
428+
break;
429+
case PERF_TYPE_RAW:
430+
/*
431+
* As per SBI v0.3 specification,
432+
* -- the upper 16 bits must be unused for a hardware raw event.
433+
* As per SBI v2.0 specification,
434+
* -- the upper 8 bits must be unused for a hardware raw event.
435+
* Bits 63:62 are used to distinguish between raw events
436+
* 00 - Hardware raw event
437+
* 10 - SBI firmware events
438+
* 11 - Risc-V platform specific firmware event
439+
*/
440+
switch (config >> 62) {
441+
case 0:
442+
if (sbi_v3_available) {
443+
/* Return error any bits [56-63] is set as it is not allowed by the spec */
444+
if (!(config & ~RISCV_PMU_RAW_EVENT_V2_MASK)) {
445+
if (econfig)
446+
*econfig = config & RISCV_PMU_RAW_EVENT_V2_MASK;
447+
ret = RISCV_PMU_RAW_EVENT_V2_IDX;
448+
}
449+
/* Return error any bits [48-63] is set as it is not allowed by the spec */
450+
} else if (!(config & ~RISCV_PMU_RAW_EVENT_MASK)) {
451+
if (econfig)
452+
*econfig = config & RISCV_PMU_RAW_EVENT_MASK;
453+
ret = RISCV_PMU_RAW_EVENT_IDX;
454+
}
455+
break;
456+
case 2:
457+
ret = (config & 0xFFFF) | (SBI_PMU_EVENT_TYPE_FW << 16);
458+
break;
459+
case 3:
460+
/*
461+
* For Risc-V platform specific firmware events
462+
* Event code - 0xFFFF
463+
* Event data - raw event encoding
464+
*/
465+
ret = SBI_PMU_EVENT_TYPE_FW << 16 | RISCV_PLAT_FW_EVENT;
466+
if (econfig)
467+
*econfig = config & RISCV_PMU_PLAT_FW_EVENT_MASK;
468+
break;
469+
default:
470+
break;
471+
}
472+
break;
473+
default:
474+
break;
475+
}
476+
477+
return ret;
478+
}
479+
EXPORT_SYMBOL_GPL(riscv_pmu_get_event_info);
480+
415481
/*
416482
* Returns the counter width of a programmable counter and number of hardware
417483
* counters. As we don't support heterogeneous CPUs yet, it is okay to just
@@ -577,68 +643,14 @@ static int pmu_sbi_event_map(struct perf_event *event, u64 *econfig)
577643
{
578644
u32 type = event->attr.type;
579645
u64 config = event->attr.config;
580-
int ret = -ENOENT;
581646

582647
/*
583648
* Ensure we are finished checking standard hardware events for
584649
* validity before allowing userspace to configure any events.
585650
*/
586651
flush_work(&check_std_events_work);
587652

588-
switch (type) {
589-
case PERF_TYPE_HARDWARE:
590-
if (config >= PERF_COUNT_HW_MAX)
591-
return -EINVAL;
592-
ret = pmu_hw_event_map[event->attr.config].event_idx;
593-
break;
594-
case PERF_TYPE_HW_CACHE:
595-
ret = pmu_event_find_cache(config);
596-
break;
597-
case PERF_TYPE_RAW:
598-
/*
599-
* As per SBI v0.3 specification,
600-
* -- the upper 16 bits must be unused for a hardware raw event.
601-
* As per SBI v2.0 specification,
602-
* -- the upper 8 bits must be unused for a hardware raw event.
603-
* Bits 63:62 are used to distinguish between raw events
604-
* 00 - Hardware raw event
605-
* 10 - SBI firmware events
606-
* 11 - Risc-V platform specific firmware event
607-
*/
608-
609-
switch (config >> 62) {
610-
case 0:
611-
if (sbi_v3_available) {
612-
if (!(config & ~RISCV_PMU_RAW_EVENT_V2_MASK)) {
613-
*econfig = config & RISCV_PMU_RAW_EVENT_V2_MASK;
614-
ret = RISCV_PMU_RAW_EVENT_V2_IDX;
615-
}
616-
} else if (!(config & ~RISCV_PMU_RAW_EVENT_MASK)) {
617-
*econfig = config & RISCV_PMU_RAW_EVENT_MASK;
618-
ret = RISCV_PMU_RAW_EVENT_IDX;
619-
}
620-
break;
621-
case 2:
622-
ret = (config & 0xFFFF) | (SBI_PMU_EVENT_TYPE_FW << 16);
623-
break;
624-
case 3:
625-
/*
626-
* For Risc-V platform specific firmware events
627-
* Event code - 0xFFFF
628-
* Event data - raw event encoding
629-
*/
630-
ret = SBI_PMU_EVENT_TYPE_FW << 16 | RISCV_PLAT_FW_EVENT;
631-
*econfig = config & RISCV_PMU_PLAT_FW_EVENT_MASK;
632-
break;
633-
default:
634-
break;
635-
}
636-
break;
637-
default:
638-
break;
639-
}
640-
641-
return ret;
653+
return riscv_pmu_get_event_info(type, config, econfig);
642654
}
643655

644656
static void pmu_sbi_snapshot_free(struct riscv_pmu *pmu)

include/linux/perf/riscv_pmu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ static inline void riscv_pmu_legacy_skip_init(void) {};
8989
struct riscv_pmu *riscv_pmu_alloc(void);
9090
#ifdef CONFIG_RISCV_PMU_SBI
9191
int riscv_pmu_get_hpm_info(u32 *hw_ctr_width, u32 *num_hw_ctr);
92+
int riscv_pmu_get_event_info(u32 type, u64 config, u64 *econfig);
9293
#endif
9394

9495
#endif /* CONFIG_RISCV_PMU */

0 commit comments

Comments
 (0)