[PATCH 1/2] KVM: arm64: Turn kvm_arm_support_pmu_v3() into a static key
Andre Przywara
andre.przywara at arm.com
Thu Jan 28 10:16:43 EST 2021
On Tue, 26 Jan 2021 15:15:20 +0000
Marc Zyngier <maz at kernel.org> wrote:
Hi Marc,
> We currently find out about the presence of a HW PMU (or the handling
> of that PMU by perf, which amounts to the same thing) in a fairly
> roundabout way, by checking the number of counters available to perf.
> That's good enough for now, but we will soon need to find about about
> that on paths where perf is out of reach (in the world switch).
>
> Instead, let's turn kvm_arm_support_pmu_v3() into a static key.
I am sure the pesky build bot has told you about it already, but this
fails when ARM_PMU is not defined, as perf_num_counters() is not
defined. It's bit nasty, since it's a generic function, so we
can't easily stub it in its original header.
Shall we find a place somewhere in arch/arm64 and provide a stub
implementation there, #ifndef CONFIG_ARM_PMU? Sounds ugly, though.
Or something else entirely?
Cheers,
Andre
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
> arch/arm64/kvm/perf.c | 10 ++++++++++
> arch/arm64/kvm/pmu-emul.c | 10 ----------
> include/kvm/arm_pmu.h | 9 +++++++--
> 3 files changed, 17 insertions(+), 12 deletions(-)
>
> diff --git a/arch/arm64/kvm/perf.c b/arch/arm64/kvm/perf.c
> index d45b8b9a4415..198fa4266b2d 100644
> --- a/arch/arm64/kvm/perf.c
> +++ b/arch/arm64/kvm/perf.c
> @@ -11,6 +11,8 @@
>
> #include <asm/kvm_emulate.h>
>
> +DEFINE_STATIC_KEY_FALSE(kvm_arm_pmu_available);
> +
> static int kvm_is_in_guest(void)
> {
> return kvm_get_running_vcpu() != NULL;
> @@ -48,6 +50,14 @@ static struct perf_guest_info_callbacks kvm_guest_cbs = {
>
> int kvm_perf_init(void)
> {
> + /*
> + * Check if HW_PERF_EVENTS are supported by checking the number of
> + * hardware performance counters. This could ensure the presence of
> + * a physical PMU and CONFIG_PERF_EVENT is selected.
> + */
> + if (perf_num_counters() > 0)
> + static_branch_enable(&kvm_arm_pmu_available);
> +
> return perf_register_guest_info_callbacks(&kvm_guest_cbs);
> }
>
> diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
> index 4ad66a532e38..44d500706ab9 100644
> --- a/arch/arm64/kvm/pmu-emul.c
> +++ b/arch/arm64/kvm/pmu-emul.c
> @@ -813,16 +813,6 @@ u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
> return val & mask;
> }
>
> -bool kvm_arm_support_pmu_v3(void)
> -{
> - /*
> - * Check if HW_PERF_EVENTS are supported by checking the number of
> - * hardware performance counters. This could ensure the presence of
> - * a physical PMU and CONFIG_PERF_EVENT is selected.
> - */
> - return (perf_num_counters() > 0);
> -}
> -
> int kvm_arm_pmu_v3_enable(struct kvm_vcpu *vcpu)
> {
> if (!kvm_vcpu_has_pmu(vcpu))
> diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
> index 8dcb3e1477bc..6fd3cda608e4 100644
> --- a/include/kvm/arm_pmu.h
> +++ b/include/kvm/arm_pmu.h
> @@ -13,6 +13,13 @@
> #define ARMV8_PMU_CYCLE_IDX (ARMV8_PMU_MAX_COUNTERS - 1)
> #define ARMV8_PMU_MAX_COUNTER_PAIRS ((ARMV8_PMU_MAX_COUNTERS + 1) >> 1)
>
> +DECLARE_STATIC_KEY_FALSE(kvm_arm_pmu_available);
> +
> +static __always_inline bool kvm_arm_support_pmu_v3(void)
> +{
> + return static_branch_likely(&kvm_arm_pmu_available);
> +}
> +
> #ifdef CONFIG_HW_PERF_EVENTS
>
> struct kvm_pmc {
> @@ -47,7 +54,6 @@ void kvm_pmu_software_increment(struct kvm_vcpu *vcpu, u64 val);
> void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val);
> void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, u64 data,
> u64 select_idx);
> -bool kvm_arm_support_pmu_v3(void);
> int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu,
> struct kvm_device_attr *attr);
> int kvm_arm_pmu_v3_get_attr(struct kvm_vcpu *vcpu,
> @@ -87,7 +93,6 @@ static inline void kvm_pmu_software_increment(struct kvm_vcpu *vcpu, u64 val) {}
> static inline void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val) {}
> static inline void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu,
> u64 data, u64 select_idx) {}
> -static inline bool kvm_arm_support_pmu_v3(void) { return false; }
> static inline int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu,
> struct kvm_device_attr *attr)
> {
More information about the linux-arm-kernel
mailing list