perf: riscv_pmu_sbi: Set SYSCTL_LEGACY by default
[platform/kernel/linux-starfive.git] / drivers / perf / riscv_pmu_sbi.c
index 9a51053..5e29226 100644 (file)
@@ -51,8 +51,9 @@ static const struct attribute_group *riscv_pmu_attr_groups[] = {
        NULL,
 };
 
-/* Allow user mode access by default */
-static int sysctl_perf_user_access __read_mostly = SYSCTL_USER_ACCESS;
+/* WORKAROUND: Allow legacy mode by default when SOC is starfive */
+static int sysctl_perf_user_access __read_mostly = SYSCTL_LEGACY;
+
 
 /*
  * RISC-V doesn't have heterogeneous harts yet. This need to be part of
@@ -510,16 +511,18 @@ static void pmu_sbi_set_scounteren(void *arg)
 {
        struct perf_event *event = (struct perf_event *)arg;
 
-       csr_write(CSR_SCOUNTEREN,
-                 csr_read(CSR_SCOUNTEREN) | (1 << pmu_sbi_csr_index(event)));
+       if (event->hw.idx != -1)
+               csr_write(CSR_SCOUNTEREN,
+                         csr_read(CSR_SCOUNTEREN) | (1 << pmu_sbi_csr_index(event)));
 }
 
 static void pmu_sbi_reset_scounteren(void *arg)
 {
        struct perf_event *event = (struct perf_event *)arg;
 
-       csr_write(CSR_SCOUNTEREN,
-                 csr_read(CSR_SCOUNTEREN) & ~(1 << pmu_sbi_csr_index(event)));
+       if (event->hw.idx != -1)
+               csr_write(CSR_SCOUNTEREN,
+                         csr_read(CSR_SCOUNTEREN) & ~(1 << pmu_sbi_csr_index(event)));
 }
 
 static void pmu_sbi_ctr_start(struct perf_event *event, u64 ival)
@@ -685,6 +688,11 @@ static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev)
 
        /* Firmware counter don't support overflow yet */
        fidx = find_first_bit(cpu_hw_evt->used_hw_ctrs, RISCV_MAX_COUNTERS);
+       if (fidx == RISCV_MAX_COUNTERS) {
+               csr_clear(CSR_SIP, BIT(riscv_pmu_irq_num));
+               return IRQ_NONE;
+       }
+
        event = cpu_hw_evt->events[fidx];
        if (!event) {
                csr_clear(CSR_SIP, BIT(riscv_pmu_irq_num));