From: Marc Zyngier <maz@kernel.org>
Reorganize these tangled headers.
* Respect the move defining the interface between KVM and PMU in its
own header asm/kvm_pmu.h
* Define an empty struct arm_pmu so it is defined for those interface
functions when compiling with CONFIG_KVM but not CONFIG_ARM_PMU
Signed-off-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Colton Lewis <coltonlewis@google.com>
---
arch/arm64/include/asm/arm_pmuv3.h | 2 +-
arch/arm64/include/asm/kvm_host.h | 15 +--------------
arch/arm64/include/asm/kvm_pmu.h | 15 +++++++++++++++
arch/arm64/kvm/debug.c | 1 +
arch/arm64/kvm/hyp/include/hyp/switch.h | 1 +
arch/arm64/kvm/pmu.c | 2 ++
arch/arm64/kvm/sys_regs.c | 1 +
include/linux/perf/arm_pmu.h | 5 +++++
virt/kvm/kvm_main.c | 1 +
9 files changed, 28 insertions(+), 15 deletions(-)
diff --git a/arch/arm64/include/asm/arm_pmuv3.h b/arch/arm64/include/asm/arm_pmuv3.h
index 8a777dec8d88..32c003a7b810 100644
--- a/arch/arm64/include/asm/arm_pmuv3.h
+++ b/arch/arm64/include/asm/arm_pmuv3.h
@@ -6,7 +6,7 @@
#ifndef __ASM_PMUV3_H
#define __ASM_PMUV3_H
-#include <asm/kvm_host.h>
+#include <asm/kvm_pmu.h>
#include <asm/cpufeature.h>
#include <asm/sysreg.h>
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 27ed26bd4381..2df76689381a 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -14,6 +14,7 @@
#include <linux/arm-smccc.h>
#include <linux/bitmap.h>
#include <linux/types.h>
+#include <linux/irq_work.h>
#include <linux/jump_label.h>
#include <linux/kvm_types.h>
#include <linux/maple_tree.h>
@@ -1487,25 +1488,11 @@ void kvm_arch_vcpu_ctxflush_fp(struct kvm_vcpu *vcpu);
void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu);
void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu);
-static inline bool kvm_pmu_counter_deferred(struct perf_event_attr *attr)
-{
- return (!has_vhe() && attr->exclude_host);
-}
-
#ifdef CONFIG_KVM
-void kvm_set_pmu_events(u64 set, struct perf_event_attr *attr);
-void kvm_clr_pmu_events(u64 clr);
-bool kvm_set_pmuserenr(u64 val);
void kvm_enable_trbe(void);
void kvm_disable_trbe(void);
void kvm_tracing_set_el1_configuration(u64 trfcr_while_in_guest);
#else
-static inline void kvm_set_pmu_events(u64 set, struct perf_event_attr *attr) {}
-static inline void kvm_clr_pmu_events(u64 clr) {}
-static inline bool kvm_set_pmuserenr(u64 val)
-{
- return false;
-}
static inline void kvm_enable_trbe(void) {}
static inline void kvm_disable_trbe(void) {}
static inline void kvm_tracing_set_el1_configuration(u64 trfcr_while_in_guest) {}
diff --git a/arch/arm64/include/asm/kvm_pmu.h b/arch/arm64/include/asm/kvm_pmu.h
index baf028d19dfc..ad3247b46838 100644
--- a/arch/arm64/include/asm/kvm_pmu.h
+++ b/arch/arm64/include/asm/kvm_pmu.h
@@ -11,9 +11,15 @@
#include <linux/kvm_types.h>
#include <linux/perf_event.h>
#include <linux/perf/arm_pmuv3.h>
+#include <linux/perf/arm_pmu.h>
#define KVM_ARMV8_PMU_MAX_COUNTERS 32
+#define kvm_pmu_counter_deferred(attr) \
+ ({ \
+ !has_vhe() && (attr)->exclude_host; \
+ })
+
#if IS_ENABLED(CONFIG_HW_PERF_EVENTS) && IS_ENABLED(CONFIG_KVM)
struct kvm_pmc {
u8 idx; /* index into the pmu->pmc array */
@@ -68,6 +74,9 @@ int kvm_arm_pmu_v3_has_attr(struct kvm_vcpu *vcpu,
int kvm_arm_pmu_v3_enable(struct kvm_vcpu *vcpu);
struct kvm_pmu_events *kvm_get_pmu_events(void);
+void kvm_set_pmu_events(u64 set, struct perf_event_attr *attr);
+void kvm_clr_pmu_events(u64 clr);
+bool kvm_set_pmuserenr(u64 val);
void kvm_vcpu_pmu_restore_guest(struct kvm_vcpu *vcpu);
void kvm_vcpu_pmu_restore_host(struct kvm_vcpu *vcpu);
void kvm_vcpu_pmu_resync_el0(void);
@@ -161,6 +170,12 @@ static inline u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
#define kvm_vcpu_has_pmu(vcpu) ({ false; })
static inline void kvm_pmu_update_vcpu_events(struct kvm_vcpu *vcpu) {}
+static inline void kvm_set_pmu_events(u64 set, struct perf_event_attr *attr) {}
+static inline void kvm_clr_pmu_events(u64 clr) {}
+static inline bool kvm_set_pmuserenr(u64 val)
+{
+ return false;
+}
static inline void kvm_vcpu_pmu_restore_guest(struct kvm_vcpu *vcpu) {}
static inline void kvm_vcpu_pmu_restore_host(struct kvm_vcpu *vcpu) {}
static inline void kvm_vcpu_reload_pmu(struct kvm_vcpu *vcpu) {}
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index 1a7dab333f55..a554c3e368dc 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -9,6 +9,7 @@
#include <linux/kvm_host.h>
#include <linux/hw_breakpoint.h>
+#include <linux/perf/arm_pmuv3.h>
#include <asm/debug-monitors.h>
#include <asm/kvm_asm.h>
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 7599844908c0..825b81749972 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -14,6 +14,7 @@
#include <linux/kvm_host.h>
#include <linux/types.h>
#include <linux/jump_label.h>
+#include <linux/perf/arm_pmuv3.h>
#include <uapi/linux/psci.h>
#include <asm/barrier.h>
diff --git a/arch/arm64/kvm/pmu.c b/arch/arm64/kvm/pmu.c
index 6b48a3d16d0d..8bfc6b0a85f6 100644
--- a/arch/arm64/kvm/pmu.c
+++ b/arch/arm64/kvm/pmu.c
@@ -8,6 +8,8 @@
#include <linux/perf/arm_pmu.h>
#include <linux/perf/arm_pmuv3.h>
+#include <asm/kvm_pmu.h>
+
static DEFINE_PER_CPU(struct kvm_pmu_events, kvm_pmu_events);
/*
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 99fdbe174202..eaff6d63ef77 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -18,6 +18,7 @@
#include <linux/printk.h>
#include <linux/uaccess.h>
#include <linux/irqchip/arm-gic-v3.h>
+#include <linux/perf/arm_pmuv3.h>
#include <asm/arm_pmuv3.h>
#include <asm/cacheflush.h>
diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h
index 6dc5e0cd76ca..fb382bcd4f4b 100644
--- a/include/linux/perf/arm_pmu.h
+++ b/include/linux/perf/arm_pmu.h
@@ -187,6 +187,11 @@ void armpmu_free_irq(int irq, int cpu);
#define ARMV8_PMU_PDEV_NAME "armv8-pmu"
+#else
+
+struct arm_pmu {
+};
+
#endif /* CONFIG_ARM_PMU */
#define ARMV8_SPE_PDEV_NAME "arm,spe-v1"
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index e2f6344256ce..25259fcf3115 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -48,6 +48,7 @@
#include <linux/lockdep.h>
#include <linux/kthread.h>
#include <linux/suspend.h>
+#include <linux/perf_event.h>
#include <asm/processor.h>
#include <asm/ioctl.h>
--
2.50.0.727.gbf7dc18ff4-goog
On Thu, Jun 26, 2025 at 08:04:40PM +0000, Colton Lewis wrote:
> From: Marc Zyngier <maz@kernel.org>
>
> Reorganize these tangled headers.
In prior versions of this series, there was some earlier text explaining that
there was a circular header dependency. In v2:
https://lore.kernel.org/linux-arm-kernel/20250620221326.1261128-6-coltonlewis@google.com/
... it said:
| asm/kvm_host.h includes asm/arm_pmu.h which includes perf/arm_pmuv3.h
| which includes asm/arm_pmuv3.h which includes asm/kvm_host.h This
| causes compilation problems why trying to use anything defined in any
| of the headers in any other headers.
Was there some reason for dropping that? It's a bit odd to start without a
problem statement.
>
> * Respect the move defining the interface between KVM and PMU in its
> own header asm/kvm_pmu.h
>
> * Define an empty struct arm_pmu so it is defined for those interface
> functions when compiling with CONFIG_KVM but not CONFIG_ARM_PMU
Which functions in particular are those? What prevents them from depending on
CONFIG_ARM_PMU?
Mark.
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> Signed-off-by: Colton Lewis <coltonlewis@google.com>
> ---
> arch/arm64/include/asm/arm_pmuv3.h | 2 +-
> arch/arm64/include/asm/kvm_host.h | 15 +--------------
> arch/arm64/include/asm/kvm_pmu.h | 15 +++++++++++++++
> arch/arm64/kvm/debug.c | 1 +
> arch/arm64/kvm/hyp/include/hyp/switch.h | 1 +
> arch/arm64/kvm/pmu.c | 2 ++
> arch/arm64/kvm/sys_regs.c | 1 +
> include/linux/perf/arm_pmu.h | 5 +++++
> virt/kvm/kvm_main.c | 1 +
> 9 files changed, 28 insertions(+), 15 deletions(-)
>
> diff --git a/arch/arm64/include/asm/arm_pmuv3.h b/arch/arm64/include/asm/arm_pmuv3.h
> index 8a777dec8d88..32c003a7b810 100644
> --- a/arch/arm64/include/asm/arm_pmuv3.h
> +++ b/arch/arm64/include/asm/arm_pmuv3.h
> @@ -6,7 +6,7 @@
> #ifndef __ASM_PMUV3_H
> #define __ASM_PMUV3_H
>
> -#include <asm/kvm_host.h>
> +#include <asm/kvm_pmu.h>
>
> #include <asm/cpufeature.h>
> #include <asm/sysreg.h>
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 27ed26bd4381..2df76689381a 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -14,6 +14,7 @@
> #include <linux/arm-smccc.h>
> #include <linux/bitmap.h>
> #include <linux/types.h>
> +#include <linux/irq_work.h>
> #include <linux/jump_label.h>
> #include <linux/kvm_types.h>
> #include <linux/maple_tree.h>
> @@ -1487,25 +1488,11 @@ void kvm_arch_vcpu_ctxflush_fp(struct kvm_vcpu *vcpu);
> void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu);
> void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu);
>
> -static inline bool kvm_pmu_counter_deferred(struct perf_event_attr *attr)
> -{
> - return (!has_vhe() && attr->exclude_host);
> -}
> -
> #ifdef CONFIG_KVM
> -void kvm_set_pmu_events(u64 set, struct perf_event_attr *attr);
> -void kvm_clr_pmu_events(u64 clr);
> -bool kvm_set_pmuserenr(u64 val);
> void kvm_enable_trbe(void);
> void kvm_disable_trbe(void);
> void kvm_tracing_set_el1_configuration(u64 trfcr_while_in_guest);
> #else
> -static inline void kvm_set_pmu_events(u64 set, struct perf_event_attr *attr) {}
> -static inline void kvm_clr_pmu_events(u64 clr) {}
> -static inline bool kvm_set_pmuserenr(u64 val)
> -{
> - return false;
> -}
> static inline void kvm_enable_trbe(void) {}
> static inline void kvm_disable_trbe(void) {}
> static inline void kvm_tracing_set_el1_configuration(u64 trfcr_while_in_guest) {}
> diff --git a/arch/arm64/include/asm/kvm_pmu.h b/arch/arm64/include/asm/kvm_pmu.h
> index baf028d19dfc..ad3247b46838 100644
> --- a/arch/arm64/include/asm/kvm_pmu.h
> +++ b/arch/arm64/include/asm/kvm_pmu.h
> @@ -11,9 +11,15 @@
> #include <linux/kvm_types.h>
> #include <linux/perf_event.h>
> #include <linux/perf/arm_pmuv3.h>
> +#include <linux/perf/arm_pmu.h>
>
> #define KVM_ARMV8_PMU_MAX_COUNTERS 32
>
> +#define kvm_pmu_counter_deferred(attr) \
> + ({ \
> + !has_vhe() && (attr)->exclude_host; \
> + })
> +
> #if IS_ENABLED(CONFIG_HW_PERF_EVENTS) && IS_ENABLED(CONFIG_KVM)
> struct kvm_pmc {
> u8 idx; /* index into the pmu->pmc array */
> @@ -68,6 +74,9 @@ int kvm_arm_pmu_v3_has_attr(struct kvm_vcpu *vcpu,
> int kvm_arm_pmu_v3_enable(struct kvm_vcpu *vcpu);
>
> struct kvm_pmu_events *kvm_get_pmu_events(void);
> +void kvm_set_pmu_events(u64 set, struct perf_event_attr *attr);
> +void kvm_clr_pmu_events(u64 clr);
> +bool kvm_set_pmuserenr(u64 val);
> void kvm_vcpu_pmu_restore_guest(struct kvm_vcpu *vcpu);
> void kvm_vcpu_pmu_restore_host(struct kvm_vcpu *vcpu);
> void kvm_vcpu_pmu_resync_el0(void);
> @@ -161,6 +170,12 @@ static inline u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
>
> #define kvm_vcpu_has_pmu(vcpu) ({ false; })
> static inline void kvm_pmu_update_vcpu_events(struct kvm_vcpu *vcpu) {}
> +static inline void kvm_set_pmu_events(u64 set, struct perf_event_attr *attr) {}
> +static inline void kvm_clr_pmu_events(u64 clr) {}
> +static inline bool kvm_set_pmuserenr(u64 val)
> +{
> + return false;
> +}
> static inline void kvm_vcpu_pmu_restore_guest(struct kvm_vcpu *vcpu) {}
> static inline void kvm_vcpu_pmu_restore_host(struct kvm_vcpu *vcpu) {}
> static inline void kvm_vcpu_reload_pmu(struct kvm_vcpu *vcpu) {}
> diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
> index 1a7dab333f55..a554c3e368dc 100644
> --- a/arch/arm64/kvm/debug.c
> +++ b/arch/arm64/kvm/debug.c
> @@ -9,6 +9,7 @@
>
> #include <linux/kvm_host.h>
> #include <linux/hw_breakpoint.h>
> +#include <linux/perf/arm_pmuv3.h>
>
> #include <asm/debug-monitors.h>
> #include <asm/kvm_asm.h>
> diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
> index 7599844908c0..825b81749972 100644
> --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
> +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
> @@ -14,6 +14,7 @@
> #include <linux/kvm_host.h>
> #include <linux/types.h>
> #include <linux/jump_label.h>
> +#include <linux/perf/arm_pmuv3.h>
> #include <uapi/linux/psci.h>
>
> #include <asm/barrier.h>
> diff --git a/arch/arm64/kvm/pmu.c b/arch/arm64/kvm/pmu.c
> index 6b48a3d16d0d..8bfc6b0a85f6 100644
> --- a/arch/arm64/kvm/pmu.c
> +++ b/arch/arm64/kvm/pmu.c
> @@ -8,6 +8,8 @@
> #include <linux/perf/arm_pmu.h>
> #include <linux/perf/arm_pmuv3.h>
>
> +#include <asm/kvm_pmu.h>
> +
> static DEFINE_PER_CPU(struct kvm_pmu_events, kvm_pmu_events);
>
> /*
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 99fdbe174202..eaff6d63ef77 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -18,6 +18,7 @@
> #include <linux/printk.h>
> #include <linux/uaccess.h>
> #include <linux/irqchip/arm-gic-v3.h>
> +#include <linux/perf/arm_pmuv3.h>
>
> #include <asm/arm_pmuv3.h>
> #include <asm/cacheflush.h>
> diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h
> index 6dc5e0cd76ca..fb382bcd4f4b 100644
> --- a/include/linux/perf/arm_pmu.h
> +++ b/include/linux/perf/arm_pmu.h
> @@ -187,6 +187,11 @@ void armpmu_free_irq(int irq, int cpu);
>
> #define ARMV8_PMU_PDEV_NAME "armv8-pmu"
>
> +#else
> +
> +struct arm_pmu {
> +};
> +
> #endif /* CONFIG_ARM_PMU */
>
> #define ARMV8_SPE_PDEV_NAME "arm,spe-v1"
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index e2f6344256ce..25259fcf3115 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -48,6 +48,7 @@
> #include <linux/lockdep.h>
> #include <linux/kthread.h>
> #include <linux/suspend.h>
> +#include <linux/perf_event.h>
>
> #include <asm/processor.h>
> #include <asm/ioctl.h>
> --
> 2.50.0.727.gbf7dc18ff4-goog
>
Mark Rutland <mark.rutland@arm.com> writes:
> On Thu, Jun 26, 2025 at 08:04:40PM +0000, Colton Lewis wrote:
>> From: Marc Zyngier <maz@kernel.org>
>> Reorganize these tangled headers.
> In prior versions of this series, there was some earlier text explaining
> that
> there was a circular header dependency. In v2:
>
> https://lore.kernel.org/linux-arm-kernel/20250620221326.1261128-6-coltonlewis@google.com/
> ... it said:
> | asm/kvm_host.h includes asm/arm_pmu.h which includes perf/arm_pmuv3.h
> | which includes asm/arm_pmuv3.h which includes asm/kvm_host.h This
> | causes compilation problems why trying to use anything defined in any
> | of the headers in any other headers.
> Was there some reason for dropping that? It's a bit odd to start without a
> problem statement.
When I rebased on top of kvm/queue, that included a patch from Sean that
changed the the problem. I thought I wrote a new description but I guess
not. I'll include in my next reroll.
The core issue is still that including *all* of kvm_host.h in
arm_pmuv3.h is a circular dependency.
asm/kvm_host.h includes asm/kvm_pmu.h includes perf/arm_pmuv3.h includes
asm/arm_pmuv3.h includes asm/kvm_host.h
Some other things in this patch are vestigial or needed later, so I
should put them in the patches where they are used.
>> * Respect the move defining the interface between KVM and PMU in its
>> own header asm/kvm_pmu.h
>> * Define an empty struct arm_pmu so it is defined for those interface
>> functions when compiling with CONFIG_KVM but not CONFIG_ARM_PMU
> Which functions in particular are those? What prevents them from
> depending on
> CONFIG_ARM_PMU?
> Mark.
Functions I introduce later. So this hunk should be in a later patch if
I need to keep it.
bool kvm_pmu_is_partitioned(struct arm_pmu *pmu);
u64 kvm_pmu_host_counter_mask(struct arm_pmu *pmu);
u64 kvm_pmu_guest_counter_mask(struct arm_pmu *pmu);
The first, at least, has to be called in non-PMU KVM code to check if we
can use my ioctl later.
I suppose in that case it's only calling a dummy definition that returns
false, so I don't need struct arm_pmu * in the argument and can just use
void *
>> Signed-off-by: Marc Zyngier <maz@kernel.org>
>> Signed-off-by: Colton Lewis <coltonlewis@google.com>
>> ---
>> arch/arm64/include/asm/arm_pmuv3.h | 2 +-
>> arch/arm64/include/asm/kvm_host.h | 15 +--------------
>> arch/arm64/include/asm/kvm_pmu.h | 15 +++++++++++++++
>> arch/arm64/kvm/debug.c | 1 +
>> arch/arm64/kvm/hyp/include/hyp/switch.h | 1 +
>> arch/arm64/kvm/pmu.c | 2 ++
>> arch/arm64/kvm/sys_regs.c | 1 +
>> include/linux/perf/arm_pmu.h | 5 +++++
>> virt/kvm/kvm_main.c | 1 +
>> 9 files changed, 28 insertions(+), 15 deletions(-)
>> diff --git a/arch/arm64/include/asm/arm_pmuv3.h
>> b/arch/arm64/include/asm/arm_pmuv3.h
>> index 8a777dec8d88..32c003a7b810 100644
>> --- a/arch/arm64/include/asm/arm_pmuv3.h
>> +++ b/arch/arm64/include/asm/arm_pmuv3.h
>> @@ -6,7 +6,7 @@
>> #ifndef __ASM_PMUV3_H
>> #define __ASM_PMUV3_H
>> -#include <asm/kvm_host.h>
>> +#include <asm/kvm_pmu.h>
>> #include <asm/cpufeature.h>
>> #include <asm/sysreg.h>
>> diff --git a/arch/arm64/include/asm/kvm_host.h
>> b/arch/arm64/include/asm/kvm_host.h
>> index 27ed26bd4381..2df76689381a 100644
>> --- a/arch/arm64/include/asm/kvm_host.h
>> +++ b/arch/arm64/include/asm/kvm_host.h
>> @@ -14,6 +14,7 @@
>> #include <linux/arm-smccc.h>
>> #include <linux/bitmap.h>
>> #include <linux/types.h>
>> +#include <linux/irq_work.h>
>> #include <linux/jump_label.h>
>> #include <linux/kvm_types.h>
>> #include <linux/maple_tree.h>
>> @@ -1487,25 +1488,11 @@ void kvm_arch_vcpu_ctxflush_fp(struct kvm_vcpu
>> *vcpu);
>> void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu);
>> void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu);
>> -static inline bool kvm_pmu_counter_deferred(struct perf_event_attr
>> *attr)
>> -{
>> - return (!has_vhe() && attr->exclude_host);
>> -}
>> -
>> #ifdef CONFIG_KVM
>> -void kvm_set_pmu_events(u64 set, struct perf_event_attr *attr);
>> -void kvm_clr_pmu_events(u64 clr);
>> -bool kvm_set_pmuserenr(u64 val);
>> void kvm_enable_trbe(void);
>> void kvm_disable_trbe(void);
>> void kvm_tracing_set_el1_configuration(u64 trfcr_while_in_guest);
>> #else
>> -static inline void kvm_set_pmu_events(u64 set, struct perf_event_attr
>> *attr) {}
>> -static inline void kvm_clr_pmu_events(u64 clr) {}
>> -static inline bool kvm_set_pmuserenr(u64 val)
>> -{
>> - return false;
>> -}
>> static inline void kvm_enable_trbe(void) {}
>> static inline void kvm_disable_trbe(void) {}
>> static inline void kvm_tracing_set_el1_configuration(u64
>> trfcr_while_in_guest) {}
>> diff --git a/arch/arm64/include/asm/kvm_pmu.h
>> b/arch/arm64/include/asm/kvm_pmu.h
>> index baf028d19dfc..ad3247b46838 100644
>> --- a/arch/arm64/include/asm/kvm_pmu.h
>> +++ b/arch/arm64/include/asm/kvm_pmu.h
>> @@ -11,9 +11,15 @@
>> #include <linux/kvm_types.h>
>> #include <linux/perf_event.h>
>> #include <linux/perf/arm_pmuv3.h>
>> +#include <linux/perf/arm_pmu.h>
>> #define KVM_ARMV8_PMU_MAX_COUNTERS 32
>> +#define kvm_pmu_counter_deferred(attr) \
>> + ({ \
>> + !has_vhe() && (attr)->exclude_host; \
>> + })
>> +
>> #if IS_ENABLED(CONFIG_HW_PERF_EVENTS) && IS_ENABLED(CONFIG_KVM)
>> struct kvm_pmc {
>> u8 idx; /* index into the pmu->pmc array */
>> @@ -68,6 +74,9 @@ int kvm_arm_pmu_v3_has_attr(struct kvm_vcpu *vcpu,
>> int kvm_arm_pmu_v3_enable(struct kvm_vcpu *vcpu);
>> struct kvm_pmu_events *kvm_get_pmu_events(void);
>> +void kvm_set_pmu_events(u64 set, struct perf_event_attr *attr);
>> +void kvm_clr_pmu_events(u64 clr);
>> +bool kvm_set_pmuserenr(u64 val);
>> void kvm_vcpu_pmu_restore_guest(struct kvm_vcpu *vcpu);
>> void kvm_vcpu_pmu_restore_host(struct kvm_vcpu *vcpu);
>> void kvm_vcpu_pmu_resync_el0(void);
>> @@ -161,6 +170,12 @@ static inline u64 kvm_pmu_get_pmceid(struct
>> kvm_vcpu *vcpu, bool pmceid1)
>> #define kvm_vcpu_has_pmu(vcpu) ({ false; })
>> static inline void kvm_pmu_update_vcpu_events(struct kvm_vcpu *vcpu) {}
>> +static inline void kvm_set_pmu_events(u64 set, struct perf_event_attr
>> *attr) {}
>> +static inline void kvm_clr_pmu_events(u64 clr) {}
>> +static inline bool kvm_set_pmuserenr(u64 val)
>> +{
>> + return false;
>> +}
>> static inline void kvm_vcpu_pmu_restore_guest(struct kvm_vcpu *vcpu) {}
>> static inline void kvm_vcpu_pmu_restore_host(struct kvm_vcpu *vcpu) {}
>> static inline void kvm_vcpu_reload_pmu(struct kvm_vcpu *vcpu) {}
>> diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
>> index 1a7dab333f55..a554c3e368dc 100644
>> --- a/arch/arm64/kvm/debug.c
>> +++ b/arch/arm64/kvm/debug.c
>> @@ -9,6 +9,7 @@
>> #include <linux/kvm_host.h>
>> #include <linux/hw_breakpoint.h>
>> +#include <linux/perf/arm_pmuv3.h>
>> #include <asm/debug-monitors.h>
>> #include <asm/kvm_asm.h>
>> diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h
>> b/arch/arm64/kvm/hyp/include/hyp/switch.h
>> index 7599844908c0..825b81749972 100644
>> --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
>> +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
>> @@ -14,6 +14,7 @@
>> #include <linux/kvm_host.h>
>> #include <linux/types.h>
>> #include <linux/jump_label.h>
>> +#include <linux/perf/arm_pmuv3.h>
>> #include <uapi/linux/psci.h>
>> #include <asm/barrier.h>
>> diff --git a/arch/arm64/kvm/pmu.c b/arch/arm64/kvm/pmu.c
>> index 6b48a3d16d0d..8bfc6b0a85f6 100644
>> --- a/arch/arm64/kvm/pmu.c
>> +++ b/arch/arm64/kvm/pmu.c
>> @@ -8,6 +8,8 @@
>> #include <linux/perf/arm_pmu.h>
>> #include <linux/perf/arm_pmuv3.h>
>> +#include <asm/kvm_pmu.h>
>> +
>> static DEFINE_PER_CPU(struct kvm_pmu_events, kvm_pmu_events);
>> /*
>> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
>> index 99fdbe174202..eaff6d63ef77 100644
>> --- a/arch/arm64/kvm/sys_regs.c
>> +++ b/arch/arm64/kvm/sys_regs.c
>> @@ -18,6 +18,7 @@
>> #include <linux/printk.h>
>> #include <linux/uaccess.h>
>> #include <linux/irqchip/arm-gic-v3.h>
>> +#include <linux/perf/arm_pmuv3.h>
>> #include <asm/arm_pmuv3.h>
>> #include <asm/cacheflush.h>
>> diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h
>> index 6dc5e0cd76ca..fb382bcd4f4b 100644
>> --- a/include/linux/perf/arm_pmu.h
>> +++ b/include/linux/perf/arm_pmu.h
>> @@ -187,6 +187,11 @@ void armpmu_free_irq(int irq, int cpu);
>> #define ARMV8_PMU_PDEV_NAME "armv8-pmu"
>> +#else
>> +
>> +struct arm_pmu {
>> +};
>> +
>> #endif /* CONFIG_ARM_PMU */
>> #define ARMV8_SPE_PDEV_NAME "arm,spe-v1"
>> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
>> index e2f6344256ce..25259fcf3115 100644
>> --- a/virt/kvm/kvm_main.c
>> +++ b/virt/kvm/kvm_main.c
>> @@ -48,6 +48,7 @@
>> #include <linux/lockdep.h>
>> #include <linux/kthread.h>
>> #include <linux/suspend.h>
>> +#include <linux/perf_event.h>
>> #include <asm/processor.h>
>> #include <asm/ioctl.h>
>> --
>> 2.50.0.727.gbf7dc18ff4-goog
© 2016 - 2026 Red Hat, Inc.