^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2015 Linaro Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Author: Shannon Zhao <shannon.zhao@linaro.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #ifndef __ASM_ARM_KVM_PMU_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #define __ASM_ARM_KVM_PMU_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/perf_event.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <asm/perf_event.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #define ARMV8_PMU_CYCLE_IDX (ARMV8_PMU_MAX_COUNTERS - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define ARMV8_PMU_MAX_COUNTER_PAIRS ((ARMV8_PMU_MAX_COUNTERS + 1) >> 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) DECLARE_STATIC_KEY_FALSE(kvm_arm_pmu_available);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static __always_inline bool kvm_arm_support_pmu_v3(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) return static_branch_likely(&kvm_arm_pmu_available);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #ifdef CONFIG_HW_PERF_EVENTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct kvm_pmc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) u8 idx; /* index into the pmu->pmc array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct perf_event *perf_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct kvm_pmu {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) int irq_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct kvm_pmc pmc[ARMV8_PMU_MAX_COUNTERS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) DECLARE_BITMAP(chained, ARMV8_PMU_MAX_COUNTER_PAIRS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) bool created;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) bool irq_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct irq_work overflow_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define kvm_arm_pmu_irq_initialized(v) ((v)->arch.pmu.irq_num >= VGIC_NR_SGIS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) u64 kvm_pmu_get_counter_value(struct kvm_vcpu *vcpu, u64 select_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) void kvm_pmu_set_counter_value(struct kvm_vcpu *vcpu, u64 select_idx, u64 val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) u64 kvm_pmu_valid_counter_mask(struct kvm_vcpu *vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) void kvm_pmu_vcpu_init(struct kvm_vcpu *vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) void kvm_pmu_vcpu_reset(struct kvm_vcpu *vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) void kvm_pmu_vcpu_destroy(struct kvm_vcpu *vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) void kvm_pmu_disable_counter_mask(struct kvm_vcpu *vcpu, u64 val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) void kvm_pmu_enable_counter_mask(struct kvm_vcpu *vcpu, u64 val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) void kvm_pmu_flush_hwstate(struct kvm_vcpu *vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) void kvm_pmu_sync_hwstate(struct kvm_vcpu *vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) bool kvm_pmu_should_notify_user(struct kvm_vcpu *vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) void kvm_pmu_update_run(struct kvm_vcpu *vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) void kvm_pmu_software_increment(struct kvm_vcpu *vcpu, u64 val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, u64 data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) u64 select_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct kvm_device_attr *attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) int kvm_arm_pmu_v3_get_attr(struct kvm_vcpu *vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct kvm_device_attr *attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) int kvm_arm_pmu_v3_has_attr(struct kvm_vcpu *vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct kvm_device_attr *attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) int kvm_arm_pmu_v3_enable(struct kvm_vcpu *vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct kvm_pmu {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define kvm_arm_pmu_irq_initialized(v) (false)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static inline u64 kvm_pmu_get_counter_value(struct kvm_vcpu *vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) u64 select_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static inline void kvm_pmu_set_counter_value(struct kvm_vcpu *vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) u64 select_idx, u64 val) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static inline u64 kvm_pmu_valid_counter_mask(struct kvm_vcpu *vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static inline void kvm_pmu_vcpu_init(struct kvm_vcpu *vcpu) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static inline void kvm_pmu_vcpu_reset(struct kvm_vcpu *vcpu) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static inline void kvm_pmu_vcpu_destroy(struct kvm_vcpu *vcpu) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static inline void kvm_pmu_disable_counter_mask(struct kvm_vcpu *vcpu, u64 val) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static inline void kvm_pmu_enable_counter_mask(struct kvm_vcpu *vcpu, u64 val) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static inline void kvm_pmu_flush_hwstate(struct kvm_vcpu *vcpu) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static inline void kvm_pmu_sync_hwstate(struct kvm_vcpu *vcpu) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static inline bool kvm_pmu_should_notify_user(struct kvm_vcpu *vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static inline void kvm_pmu_update_run(struct kvm_vcpu *vcpu) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static inline void kvm_pmu_software_increment(struct kvm_vcpu *vcpu, u64 val) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static inline void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static inline void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) u64 data, u64 select_idx) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static inline int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct kvm_device_attr *attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static inline int kvm_arm_pmu_v3_get_attr(struct kvm_vcpu *vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct kvm_device_attr *attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static inline int kvm_arm_pmu_v3_has_attr(struct kvm_vcpu *vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct kvm_device_attr *attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static inline int kvm_arm_pmu_v3_enable(struct kvm_vcpu *vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static inline u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #endif