lib: sbi_pmu: Fix the counter info function
authorAtish Patra <atishp@rivosinc.com>
Thu, 7 Dec 2023 22:23:50 +0000 (14:23 -0800)
committerAnup Patel <anup@brainfault.org>
Fri, 8 Dec 2023 17:20:23 +0000 (22:50 +0530)
The counter info should only return valid hardware counters for the ones
set in the counter mask. Otherwise, it will report incorrect number of
hardware counters to the supervisor if the platform has discontiguous
counters.

Fixes: c744ed77b18c ("lib: sbi_pmu: Enable noncontigous hpm event and counters")
Signed-off-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
include/sbi/sbi_pmu.h
lib/sbi/sbi_pmu.c

index d63149cde8ad22716f0d90b34f13a9dfb9de73b4..7d32a4da31d318ffee8f4cd99b8632216c8e0dbb 100644 (file)
@@ -23,6 +23,7 @@ struct sbi_scratch;
 #define SBI_PMU_HW_CTR_MAX 32
 #define SBI_PMU_CTR_MAX           (SBI_PMU_HW_CTR_MAX + SBI_PMU_FW_CTR_MAX)
 #define SBI_PMU_FIXED_CTR_MASK 0x07
+#define SBI_PMU_CY_IR_MASK     0x05
 
 struct sbi_pmu_device {
        /** Name of the PMU platform device */
index 5f70730e4022e8fab7b5a0dc00c7b2c388df26ea..6209ccc95d9129df7be04536d69aafe1cc4da0ca 100644 (file)
@@ -899,13 +899,17 @@ int sbi_pmu_ctr_get_info(uint32_t cidx, unsigned long *ctr_info)
        int width;
        union sbi_pmu_ctr_info cinfo = {0};
        struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
+       unsigned long counter_mask = (unsigned long)sbi_hart_mhpm_mask(scratch) |
+                                    SBI_PMU_CY_IR_MASK;
 
-       /* Sanity check. Counter1 is not mapped at all */
-       if (cidx >= total_ctrs || cidx == 1)
+       /* Sanity check */
+       if (cidx >= total_ctrs)
                return SBI_EINVAL;
 
        /* We have 31 HW counters with 31 being the last index(MHPMCOUNTER31) */
        if (cidx < num_hw_ctrs) {
+               if (!(__test_bit(cidx, &counter_mask)))
+                       return SBI_EINVAL;
                cinfo.type = SBI_PMU_CTR_TYPE_HW;
                cinfo.csr = CSR_CYCLE + cidx;
                /* mcycle & minstret are always 64 bit */