[tip: perf/core] perf: Use EXPORT_SYMBOL_FOR_KVM() for the mediated APIs

tip-bot2 for Peter Zijlstra posted 1 patch 1 month, 3 weeks ago
There is a newer version of this series
arch/x86/events/core.c | 5 +++--
kernel/events/core.c   | 5 +++--
2 files changed, 6 insertions(+), 4 deletions(-)
[tip: perf/core] perf: Use EXPORT_SYMBOL_FOR_KVM() for the mediated APIs
Posted by tip-bot2 for Peter Zijlstra 1 month, 3 weeks ago
The following commit has been merged into the perf/core branch of tip:

Commit-ID:     23faa33d88df6d126cebd3121ea2cff3586e7b95
Gitweb:        https://git.kernel.org/tip/23faa33d88df6d126cebd3121ea2cff3586e7b95
Author:        Peter Zijlstra <peterz@infradead.org>
AuthorDate:    Wed, 17 Dec 2025 13:23:59 +01:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 17 Dec 2025 13:31:09 +01:00

perf: Use EXPORT_SYMBOL_FOR_KVM() for the mediated APIs

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20251208115156.GE3707891@noisy.programming.kicks-ass.net
---
 arch/x86/events/core.c | 5 +++--
 kernel/events/core.c   | 5 +++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index df7a32b..0ecac94 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -30,6 +30,7 @@
 #include <linux/device.h>
 #include <linux/nospec.h>
 #include <linux/static_call.h>
+#include <linux/kvm_types.h>
 
 #include <asm/apic.h>
 #include <asm/stacktrace.h>
@@ -1771,14 +1772,14 @@ void perf_load_guest_lvtpc(u32 guest_lvtpc)
 		   APIC_DM_FIXED | PERF_GUEST_MEDIATED_PMI_VECTOR | masked);
 	this_cpu_write(guest_lvtpc_loaded, true);
 }
-EXPORT_SYMBOL_FOR_MODULES(perf_load_guest_lvtpc, "kvm");
+EXPORT_SYMBOL_FOR_KVM(perf_load_guest_lvtpc);
 
 void perf_put_guest_lvtpc(void)
 {
 	this_cpu_write(guest_lvtpc_loaded, false);
 	apic_write(APIC_LVTPC, APIC_DM_NMI);
 }
-EXPORT_SYMBOL_FOR_MODULES(perf_put_guest_lvtpc, "kvm");
+EXPORT_SYMBOL_FOR_KVM(perf_put_guest_lvtpc);
 #endif /* CONFIG_PERF_GUEST_MEDIATED_PMU */
 
 static int
diff --git a/kernel/events/core.c b/kernel/events/core.c
index e6a4b1e..376fb07 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -57,6 +57,7 @@
 #include <linux/task_work.h>
 #include <linux/percpu-rwsem.h>
 #include <linux/unwind_deferred.h>
+#include <linux/kvm_types.h>
 
 #include "internal.h"
 
@@ -6388,7 +6389,7 @@ int perf_create_mediated_pmu(void)
 	atomic_inc(&nr_mediated_pmu_vms);
 	return 0;
 }
-EXPORT_SYMBOL_GPL(perf_create_mediated_pmu);
+EXPORT_SYMBOL_FOR_KVM(perf_create_mediated_pmu);
 
 void perf_release_mediated_pmu(void)
 {
@@ -6397,7 +6398,7 @@ void perf_release_mediated_pmu(void)
 
 	atomic_dec(&nr_mediated_pmu_vms);
 }
-EXPORT_SYMBOL_GPL(perf_release_mediated_pmu);
+EXPORT_SYMBOL_FOR_KVM(perf_release_mediated_pmu);
 
 /* When loading a guest's mediated PMU, schedule out all exclude_guest events. */
 void perf_load_guest_context(void)
Re: [tip: perf/core] perf: Use EXPORT_SYMBOL_FOR_KVM() for the mediated APIs
Posted by Peter Zijlstra 1 month, 3 weeks ago
On Wed, Dec 17, 2025 at 12:37:57PM -0000, tip-bot2 for Peter Zijlstra wrote:
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index e6a4b1e..376fb07 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -57,6 +57,7 @@
>  #include <linux/task_work.h>
>  #include <linux/percpu-rwsem.h>
>  #include <linux/unwind_deferred.h>
> +#include <linux/kvm_types.h>
>  
>  #include "internal.h"
>  
> @@ -6388,7 +6389,7 @@ int perf_create_mediated_pmu(void)
>  	atomic_inc(&nr_mediated_pmu_vms);
>  	return 0;
>  }
> -EXPORT_SYMBOL_GPL(perf_create_mediated_pmu);
> +EXPORT_SYMBOL_FOR_KVM(perf_create_mediated_pmu);
>  
>  void perf_release_mediated_pmu(void)
>  {
> @@ -6397,7 +6398,7 @@ void perf_release_mediated_pmu(void)
>  
>  	atomic_dec(&nr_mediated_pmu_vms);
>  }
> -EXPORT_SYMBOL_GPL(perf_release_mediated_pmu);
> +EXPORT_SYMBOL_FOR_KVM(perf_release_mediated_pmu);
>  
>  /* When loading a guest's mediated PMU, schedule out all exclude_guest events. */
>  void perf_load_guest_context(void)

Bah, so the !KVM architectures hate on this.

Sean, would something like this be acceptable?

---
Subject: kvm: Fix linux/kvm_types.h for !KVM architectures

As is, <linux/kvm_types.h> hard relies on architectures having
<asm/kvm_types.h> which (obviously) breaks for architectures that don't
have KVM support.

This means generic code (kernel/events/ in this case) cannot use
EXPORT_SYMBOL_FOR_KVM().

Rearrange things just so that <linux/kvm_types.h> becomes usable and
provides the (expected) empty stub for EXPORT_SYMBOL_FOR_KVM() for !KVM.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
diff --git a/include/linux/kvm_types.h b/include/linux/kvm_types.h
index a568d8e6f4e8..a4cc13e41eec 100644
--- a/include/linux/kvm_types.h
+++ b/include/linux/kvm_types.h
@@ -6,6 +6,8 @@
 #include <linux/bits.h>
 #include <linux/export.h>
 #include <linux/types.h>
+
+#ifdef CONFIG_KVM
 #include <asm/kvm_types.h>
 
 #ifdef KVM_SUB_MODULES
@@ -20,13 +22,14 @@
  * if there are no submodules, e.g. to allow suppressing exports if KVM=m, but
  * kvm.ko won't actually be built (due to lack of at least one submodule).
  */
-#ifndef EXPORT_SYMBOL_FOR_KVM
-#if IS_MODULE(CONFIG_KVM)
+#if defined(EXPORT_SYMBOL_FOR_KVM) && IS_MODULE(CONFIG_KVM)
 #define EXPORT_SYMBOL_FOR_KVM(symbol) EXPORT_SYMBOL_FOR_MODULES(symbol, "kvm")
-#else
-#define EXPORT_SYMBOL_FOR_KVM(symbol)
 #endif /* IS_MODULE(CONFIG_KVM) */
-#endif /* EXPORT_SYMBOL_FOR_KVM */
+#endif /* KVM_SUB_MODULES */
+#endif
+
+#ifndef EXPORT_SYMBOL_FOR_KVM
+#define EXPORTEXPORT_SYMBOL_FOR_KVM(symbol)
 #endif
 
 #ifndef __ASSEMBLER__
Re: [tip: perf/core] perf: Use EXPORT_SYMBOL_FOR_KVM() for the mediated APIs
Posted by Peter Zijlstra 1 month, 3 weeks ago
On Thu, Dec 18, 2025 at 09:31:09AM +0100, Peter Zijlstra wrote:
> On Wed, Dec 17, 2025 at 12:37:57PM -0000, tip-bot2 for Peter Zijlstra wrote:
> > diff --git a/kernel/events/core.c b/kernel/events/core.c
> > index e6a4b1e..376fb07 100644
> > --- a/kernel/events/core.c
> > +++ b/kernel/events/core.c
> > @@ -57,6 +57,7 @@
> >  #include <linux/task_work.h>
> >  #include <linux/percpu-rwsem.h>
> >  #include <linux/unwind_deferred.h>
> > +#include <linux/kvm_types.h>
> >  
> >  #include "internal.h"
> >  
> > @@ -6388,7 +6389,7 @@ int perf_create_mediated_pmu(void)
> >  	atomic_inc(&nr_mediated_pmu_vms);
> >  	return 0;
> >  }
> > -EXPORT_SYMBOL_GPL(perf_create_mediated_pmu);
> > +EXPORT_SYMBOL_FOR_KVM(perf_create_mediated_pmu);
> >  
> >  void perf_release_mediated_pmu(void)
> >  {
> > @@ -6397,7 +6398,7 @@ void perf_release_mediated_pmu(void)
> >  
> >  	atomic_dec(&nr_mediated_pmu_vms);
> >  }
> > -EXPORT_SYMBOL_GPL(perf_release_mediated_pmu);
> > +EXPORT_SYMBOL_FOR_KVM(perf_release_mediated_pmu);
> >  
> >  /* When loading a guest's mediated PMU, schedule out all exclude_guest events. */
> >  void perf_load_guest_context(void)
> 
> Bah, so the !KVM architectures hate on this.
> 
> Sean, would something like this be acceptable?

Hmm, the other option is doing something like so:

diff --git a/kernel/events/core.c b/kernel/events/core.c
index 376fb07d869b..014d832e8eaa 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -57,7 +57,6 @@
 #include <linux/task_work.h>
 #include <linux/percpu-rwsem.h>
 #include <linux/unwind_deferred.h>
-#include <linux/kvm_types.h>
 
 #include "internal.h"
 
@@ -6325,6 +6324,8 @@ u64 perf_event_pause(struct perf_event *event, bool reset)
 EXPORT_SYMBOL_GPL(perf_event_pause);
 
 #ifdef CONFIG_PERF_GUEST_MEDIATED_PMU
+#include <linux/kvm_types.h>
+
 static atomic_t nr_include_guest_events __read_mostly;
 
 static atomic_t nr_mediated_pmu_vms __read_mostly;

> ---
> Subject: kvm: Fix linux/kvm_types.h for !KVM architectures
> 
> As is, <linux/kvm_types.h> hard relies on architectures having
> <asm/kvm_types.h> which (obviously) breaks for architectures that don't
> have KVM support.
> 
> This means generic code (kernel/events/ in this case) cannot use
> EXPORT_SYMBOL_FOR_KVM().
> 
> Rearrange things just so that <linux/kvm_types.h> becomes usable and
> provides the (expected) empty stub for EXPORT_SYMBOL_FOR_KVM() for !KVM.
> 
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> ---
> diff --git a/include/linux/kvm_types.h b/include/linux/kvm_types.h
> index a568d8e6f4e8..a4cc13e41eec 100644
> --- a/include/linux/kvm_types.h
> +++ b/include/linux/kvm_types.h
> @@ -6,6 +6,8 @@
>  #include <linux/bits.h>
>  #include <linux/export.h>
>  #include <linux/types.h>
> +
> +#ifdef CONFIG_KVM
>  #include <asm/kvm_types.h>
>  
>  #ifdef KVM_SUB_MODULES
> @@ -20,13 +22,14 @@
>   * if there are no submodules, e.g. to allow suppressing exports if KVM=m, but
>   * kvm.ko won't actually be built (due to lack of at least one submodule).
>   */
> -#ifndef EXPORT_SYMBOL_FOR_KVM
> -#if IS_MODULE(CONFIG_KVM)
> +#if defined(EXPORT_SYMBOL_FOR_KVM) && IS_MODULE(CONFIG_KVM)
>  #define EXPORT_SYMBOL_FOR_KVM(symbol) EXPORT_SYMBOL_FOR_MODULES(symbol, "kvm")
> -#else
> -#define EXPORT_SYMBOL_FOR_KVM(symbol)
>  #endif /* IS_MODULE(CONFIG_KVM) */
> -#endif /* EXPORT_SYMBOL_FOR_KVM */
> +#endif /* KVM_SUB_MODULES */
> +#endif
> +
> +#ifndef EXPORT_SYMBOL_FOR_KVM
> +#define EXPORTEXPORT_SYMBOL_FOR_KVM(symbol)
>  #endif
>  
>  #ifndef __ASSEMBLER__
Re: [tip: perf/core] perf: Use EXPORT_SYMBOL_FOR_KVM() for the mediated APIs
Posted by Sean Christopherson 1 month, 3 weeks ago
On Thu, Dec 18, 2025, Peter Zijlstra wrote:
> On Thu, Dec 18, 2025 at 09:31:09AM +0100, Peter Zijlstra wrote:
> > On Wed, Dec 17, 2025 at 12:37:57PM -0000, tip-bot2 for Peter Zijlstra wrote:
> > > diff --git a/kernel/events/core.c b/kernel/events/core.c
> > > index e6a4b1e..376fb07 100644
> > > --- a/kernel/events/core.c
> > > +++ b/kernel/events/core.c
> > > @@ -57,6 +57,7 @@
> > >  #include <linux/task_work.h>
> > >  #include <linux/percpu-rwsem.h>
> > >  #include <linux/unwind_deferred.h>
> > > +#include <linux/kvm_types.h>
> > Bah, so the !KVM architectures hate on this.
> > 
> > Sean, would something like this be acceptable?
> 
> Hmm, the other option is doing something like so:
> 
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index 376fb07d869b..014d832e8eaa 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -57,7 +57,6 @@
>  #include <linux/task_work.h>
>  #include <linux/percpu-rwsem.h>
>  #include <linux/unwind_deferred.h>
> -#include <linux/kvm_types.h>
>  
>  #include "internal.h"
>  
> @@ -6325,6 +6324,8 @@ u64 perf_event_pause(struct perf_event *event, bool reset)
>  EXPORT_SYMBOL_GPL(perf_event_pause);
>  
>  #ifdef CONFIG_PERF_GUEST_MEDIATED_PMU
> +#include <linux/kvm_types.h>

Hrm, quick and dirty, but I don't love the idea of punting on the underlying
issue, because not being able to include kvm_types.h will be a big deterrent to
using EXPORT_SYMBOL_FOR_KVM().

>  static atomic_t nr_include_guest_events __read_mostly;
>  
>  static atomic_t nr_mediated_pmu_vms __read_mostly;
> 
> > ---
> > Subject: kvm: Fix linux/kvm_types.h for !KVM architectures
> > 
> > As is, <linux/kvm_types.h> hard relies on architectures having
> > <asm/kvm_types.h> which (obviously) breaks for architectures that don't
> > have KVM support.
> > 
> > This means generic code (kernel/events/ in this case) cannot use
> > EXPORT_SYMBOL_FOR_KVM().
> > 
> > Rearrange things just so that <linux/kvm_types.h> becomes usable and
> > provides the (expected) empty stub for EXPORT_SYMBOL_FOR_KVM() for !KVM.
> > 
> > Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> > ---
> > diff --git a/include/linux/kvm_types.h b/include/linux/kvm_types.h
> > index a568d8e6f4e8..a4cc13e41eec 100644
> > --- a/include/linux/kvm_types.h
> > +++ b/include/linux/kvm_types.h
> > @@ -6,6 +6,8 @@
> >  #include <linux/bits.h>
> >  #include <linux/export.h>
> >  #include <linux/types.h>
> > +
> > +#ifdef CONFIG_KVM
> >  #include <asm/kvm_types.h>

This won't work, because asm/kvm_types.h #defines KVM_ARCH_NR_OBJS_PER_MEMORY_CACHE,
which guards the "struct kvm_mmu_memory_cache" definition.  E.g. on x86 with
CONFIG_KVM=n, that yields errors like:

  In file included from include/linux/kvm_host.h:45,
                   from arch/x86/events/intel/core.c:17:
  arch/x86/include/asm/kvm_host.h:854:37: error: field ‘mmu_pte_list_desc_cache’ has incomplete type
    854 |         struct kvm_mmu_memory_cache mmu_pte_list_desc_cache;
        |                                     ^~~~~~~~~~~~~~~~~~~~~~~


In general, I'm hesitant to guard an include with a conditional Kconfig, precisely
because doing so has a tendency to result in wonky, config-specific build errors.

Rather than gate the check on KVM being enabled, what if we restrict the asm
include to architectures that support KVM in any capacity?  Alternatively, we
could add a HAVE_KVM, but I'd rather not add HAVE_KVM, because then we'll end up
with the same mess if architectures get clever and conditionally select HAVE_KVM
(IIRC, that's exactly what happened when HAVE_KVM was a thing in the past).

Compiled tested on all KVM architectures along with csky (and an include of
kvm_types.h in init/main.c).

--
From: Sean Christopherson <seanjc@google.com>
Date: Thu, 18 Dec 2025 15:47:59 +0000
Subject: [PATCH] KVM: Allow linux/kvm_types.h to be included on non-KVM
 architectures

Include the arch-defined asm/kvm_types.h if and only if the kernel is
being compiled for an architecture that supports KVM so that kvm_types.h
can be included in generic code without having to guard _those_ includes,
and without having to add "generic-y += kvm_types.h" for all architectures
that don't support KVM.

Assert that KVM=n if asm/kvm_types.h isn't included to provide a more
helpful error message if an arch name changes (highly unlikely) or a new
arch that supports KVM comes along.

Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 include/linux/kvm_types.h | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/include/linux/kvm_types.h b/include/linux/kvm_types.h
index a568d8e6f4e8..797721e298df 100644
--- a/include/linux/kvm_types.h
+++ b/include/linux/kvm_types.h
@@ -6,7 +6,23 @@
 #include <linux/bits.h>
 #include <linux/export.h>
 #include <linux/types.h>
+
+/*
+ * Include the arch-defined kvm_types.h if and only if the target architecture
+ * supports KVM, so that linux/kvm_types.h can be included in generic code
+ * without requiring _all_ architectures to add generic-y += kvm_types.h.
+ */
+#if defined(CONFIG_ARM64)	|| \
+    defined(CONFIG_LOONGARCH)	|| \
+    defined(CONFIG_MIPS)	|| \
+    defined(CONFIG_PPC)		|| \
+    defined(CONFIG_RISCV)	|| \
+    defined(CONFIG_S390)	|| \
+    defined(CONFIG_X86)
 #include <asm/kvm_types.h>
+#else
+static_assert(!IS_ENABLED(CONFIG_KVM));
+#endif
 
 #ifdef KVM_SUB_MODULES
 #define EXPORT_SYMBOL_FOR_KVM_INTERNAL(symbol) \

base-commit: 8f0b4cce4481fb22653697cced8d0d04027cb1e8
-- 
Re: [tip: perf/core] perf: Use EXPORT_SYMBOL_FOR_KVM() for the mediated APIs
Posted by Peter Zijlstra 1 month, 2 weeks ago
On Thu, Dec 18, 2025 at 10:40:51AM -0800, Sean Christopherson wrote:


> Include the arch-defined asm/kvm_types.h if and only if the kernel is
> being compiled for an architecture that supports KVM so that kvm_types.h
> can be included in generic code without having to guard _those_ includes,
> and without having to add "generic-y += kvm_types.h" for all architectures
> that don't support KVM.

Something jogged my brain and the below seems to work for the few
architectures I've tried. Let me update the patch and see if the build
robot still finds fail.

---
diff --git a/include/asm-generic/Kbuild b/include/asm-generic/Kbuild
index 295c94a3ccc1..9aff61e7b8f2 100644
--- a/include/asm-generic/Kbuild
+++ b/include/asm-generic/Kbuild
@@ -32,6 +32,7 @@ mandatory-y += irq_work.h
 mandatory-y += kdebug.h
 mandatory-y += kmap_size.h
 mandatory-y += kprobes.h
+mandatory-y += kvm_types.h
 mandatory-y += linkage.h
 mandatory-y += local.h
 mandatory-y += local64.h
Re: [tip: perf/core] perf: Use EXPORT_SYMBOL_FOR_KVM() for the mediated APIs
Posted by Sean Christopherson 1 month, 2 weeks ago
On Fri, Dec 19, 2025, Peter Zijlstra wrote:
> On Thu, Dec 18, 2025 at 10:40:51AM -0800, Sean Christopherson wrote:
> 
> 
> > Include the arch-defined asm/kvm_types.h if and only if the kernel is
> > being compiled for an architecture that supports KVM so that kvm_types.h
> > can be included in generic code without having to guard _those_ includes,
> > and without having to add "generic-y += kvm_types.h" for all architectures
> > that don't support KVM.
> 
> Something jogged my brain and the below seems to work for the few
> architectures I've tried. Let me update the patch and see if the build
> robot still finds fail.

Nice!  Works on my end as well.  Just when I think I've learned most of the
build system's tricks...

> ---
> diff --git a/include/asm-generic/Kbuild b/include/asm-generic/Kbuild
> index 295c94a3ccc1..9aff61e7b8f2 100644
> --- a/include/asm-generic/Kbuild
> +++ b/include/asm-generic/Kbuild
> @@ -32,6 +32,7 @@ mandatory-y += irq_work.h
>  mandatory-y += kdebug.h
>  mandatory-y += kmap_size.h
>  mandatory-y += kprobes.h
> +mandatory-y += kvm_types.h
>  mandatory-y += linkage.h
>  mandatory-y += local.h
>  mandatory-y += local64.h