1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Copyright (c) 2023 Rivos Inc 4 * 5 * Authors: 6 * Atish Patra <atishp@rivosinc.com> 7 */ 8 9 #ifndef __KVM_VCPU_RISCV_PMU_H 10 #define __KVM_VCPU_RISCV_PMU_H 11 12 #include <linux/perf/riscv_pmu.h> 13 #include <asm/sbi.h> 14 15 #ifdef CONFIG_RISCV_PMU_SBI 16 #define RISCV_KVM_MAX_FW_CTRS 32 17 #define RISCV_KVM_MAX_HW_CTRS 32 18 #define RISCV_KVM_MAX_COUNTERS (RISCV_KVM_MAX_HW_CTRS + RISCV_KVM_MAX_FW_CTRS) 19 static_assert(RISCV_KVM_MAX_COUNTERS <= 64); 20 21 struct kvm_fw_event { 22 /* Current value of the event */ 23 unsigned long value; 24 25 /* Event monitoring status */ 26 bool started; 27 }; 28 29 /* Per virtual pmu counter data */ 30 struct kvm_pmc { 31 u8 idx; 32 struct perf_event *perf_event; 33 u64 counter_val; 34 union sbi_pmu_ctr_info cinfo; 35 /* Event monitoring status */ 36 bool started; 37 /* Monitoring event ID */ 38 unsigned long event_idx; 39 }; 40 41 /* PMU data structure per vcpu */ 42 struct kvm_pmu { 43 struct kvm_pmc pmc[RISCV_KVM_MAX_COUNTERS]; 44 struct kvm_fw_event fw_event[RISCV_KVM_MAX_FW_CTRS]; 45 /* Number of the virtual firmware counters available */ 46 int num_fw_ctrs; 47 /* Number of the virtual hardware counters available */ 48 int num_hw_ctrs; 49 /* A flag to indicate that pmu initialization is done */ 50 bool init_done; 51 /* Bit map of all the virtual counter used */ 52 DECLARE_BITMAP(pmc_in_use, RISCV_KVM_MAX_COUNTERS); 53 }; 54 55 #define vcpu_to_pmu(vcpu) (&(vcpu)->arch.pmu_context) 56 #define pmu_to_vcpu(pmu) (container_of((pmu), struct kvm_vcpu, arch.pmu_context)) 57 58 #if defined(CONFIG_32BIT) 59 #define KVM_RISCV_VCPU_HPMCOUNTER_CSR_FUNCS \ 60 {.base = CSR_CYCLEH, .count = 31, .func = kvm_riscv_vcpu_pmu_read_hpm }, \ 61 {.base = CSR_CYCLE, .count = 31, .func = kvm_riscv_vcpu_pmu_read_hpm }, 62 #else 63 #define KVM_RISCV_VCPU_HPMCOUNTER_CSR_FUNCS \ 64 {.base = CSR_CYCLE, .count = 31, .func = kvm_riscv_vcpu_pmu_read_hpm }, 65 #endif 66 67 int kvm_riscv_vcpu_pmu_incr_fw(struct kvm_vcpu *vcpu, unsigned long fid); 68 int kvm_riscv_vcpu_pmu_read_hpm(struct kvm_vcpu *vcpu, unsigned int csr_num, 69 unsigned long *val, unsigned long new_val, 70 unsigned long wr_mask); 71 72 int kvm_riscv_vcpu_pmu_num_ctrs(struct kvm_vcpu *vcpu, struct kvm_vcpu_sbi_return *retdata); 73 int kvm_riscv_vcpu_pmu_ctr_info(struct kvm_vcpu *vcpu, unsigned long cidx, 74 struct kvm_vcpu_sbi_return *retdata); 75 int kvm_riscv_vcpu_pmu_ctr_start(struct kvm_vcpu *vcpu, unsigned long ctr_base, 76 unsigned long ctr_mask, unsigned long flags, u64 ival, 77 struct kvm_vcpu_sbi_return *retdata); 78 int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_base, 79 unsigned long ctr_mask, unsigned long flags, 80 struct kvm_vcpu_sbi_return *retdata); 81 int kvm_riscv_vcpu_pmu_ctr_cfg_match(struct kvm_vcpu *vcpu, unsigned long ctr_base, 82 unsigned long ctr_mask, unsigned long flags, 83 unsigned long eidx, u64 evtdata, 84 struct kvm_vcpu_sbi_return *retdata); 85 int kvm_riscv_vcpu_pmu_ctr_read(struct kvm_vcpu *vcpu, unsigned long cidx, 86 struct kvm_vcpu_sbi_return *retdata); 87 void kvm_riscv_vcpu_pmu_init(struct kvm_vcpu *vcpu); 88 void kvm_riscv_vcpu_pmu_deinit(struct kvm_vcpu *vcpu); 89 void kvm_riscv_vcpu_pmu_reset(struct kvm_vcpu *vcpu); 90 91 #else 92 struct kvm_pmu { 93 }; 94 95 #define KVM_RISCV_VCPU_HPMCOUNTER_CSR_FUNCS \ 96 {.base = 0, .count = 0, .func = NULL }, 97 98 static inline void kvm_riscv_vcpu_pmu_init(struct kvm_vcpu *vcpu) {} 99 static inline int kvm_riscv_vcpu_pmu_incr_fw(struct kvm_vcpu *vcpu, unsigned long fid) 100 { 101 return 0; 102 } 103 104 static inline void kvm_riscv_vcpu_pmu_deinit(struct kvm_vcpu *vcpu) {} 105 static inline void kvm_riscv_vcpu_pmu_reset(struct kvm_vcpu *vcpu) {} 106 #endif /* CONFIG_RISCV_PMU_SBI */ 107 #endif /* !__KVM_VCPU_RISCV_PMU_H */ 108