Linux Audio

Check our new training course

Loading...
  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)
 19static_assert(RISCV_KVM_MAX_COUNTERS <= 64);
 20
 21struct 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 */
 30struct 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 */
 42struct 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
 67int kvm_riscv_vcpu_pmu_incr_fw(struct kvm_vcpu *vcpu, unsigned long fid);
 68int 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
 72int kvm_riscv_vcpu_pmu_num_ctrs(struct kvm_vcpu *vcpu, struct kvm_vcpu_sbi_return *retdata);
 73int kvm_riscv_vcpu_pmu_ctr_info(struct kvm_vcpu *vcpu, unsigned long cidx,
 74				struct kvm_vcpu_sbi_return *retdata);
 75int 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);
 78int 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);
 81int 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);
 85int kvm_riscv_vcpu_pmu_ctr_read(struct kvm_vcpu *vcpu, unsigned long cidx,
 86				struct kvm_vcpu_sbi_return *retdata);
 87void kvm_riscv_vcpu_pmu_init(struct kvm_vcpu *vcpu);
 88void kvm_riscv_vcpu_pmu_deinit(struct kvm_vcpu *vcpu);
 89void kvm_riscv_vcpu_pmu_reset(struct kvm_vcpu *vcpu);
 90
 91#else
 92struct kvm_pmu {
 93};
 94
 95#define KVM_RISCV_VCPU_HPMCOUNTER_CSR_FUNCS \
 96{.base = 0,	.count = 0,	.func = NULL },
 97
 98static inline void kvm_riscv_vcpu_pmu_init(struct kvm_vcpu *vcpu) {}
 99static inline int kvm_riscv_vcpu_pmu_incr_fw(struct kvm_vcpu *vcpu, unsigned long fid)
100{
101	return 0;
102}
103
104static inline void kvm_riscv_vcpu_pmu_deinit(struct kvm_vcpu *vcpu) {}
105static inline void kvm_riscv_vcpu_pmu_reset(struct kvm_vcpu *vcpu) {}
106#endif /* CONFIG_RISCV_PMU_SBI */
107#endif /* !__KVM_VCPU_RISCV_PMU_H */