Re: [PATCH v4 1/5] KVM: x86: Consolidate CPUID fault handling for emulator and interception logic

From: Sean Christopherson

Date: Thu May 28 2026 - 12:41:20 EST


On Thu, May 28, 2026, Peter Zijlstra wrote:
> On Wed, May 27, 2026 at 10:43:43AM -0700, Jim Mattson wrote:
>
> > [jim: Add EXPORT_STATIC_CALL_GPL(kvm_x86_get_cpl) so that KVM vendor
> > modules can call kvm_is_cpuid_allowed(). Fix typo in commit message.]
>
> > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> > index 1578c0ecbbd1..72bd3cddb026 100644
> > --- a/arch/x86/kvm/x86.c
> > +++ b/arch/x86/kvm/x86.c
> > @@ -151,6 +151,7 @@ struct kvm_x86_ops kvm_x86_ops __read_mostly;
> > #include <asm/kvm-x86-ops.h>
> > EXPORT_STATIC_CALL_GPL(kvm_x86_get_cs_db_l_bits);
> > EXPORT_STATIC_CALL_GPL(kvm_x86_cache_reg);
> > +EXPORT_STATIC_CALL_GPL(kvm_x86_get_cpl);
>
> Are you aware of the distinction between EXPORT_STATIC_CALL_GPL() and
> EXPORT_STATIC_CALL_TRAMP_GPL() ?

No, but it's a moot point at the moment, because EXPORT_STATIC_CALL_TRAMP_GPL()
doesn't actually work?

For CONFIG_HAVE_STATIC_CALL_INLINE=y, __static_call() references the key

/*
* __ADDRESSABLE() is used to ensure the key symbol doesn't get stripped from
* the symbol table so that objtool can reference it when it generates the
* .static_call_sites section.
*/
#define __STATIC_CALL_ADDRESSABLE(name) \
__ADDRESSABLE(STATIC_CALL_KEY(name))

#define __static_call(name) \
({ \
__STATIC_CALL_ADDRESSABLE(name); \
__raw_static_call(name); \
})

which leads to

ERROR: modpost: "__SCK__kvm_x86_cache_reg" [arch/x86/kvm/kvm-intel.ko] undefined!
ERROR: modpost: "__SCK__kvm_x86_get_cpl" [arch/x86/kvm/kvm-intel.ko] undefined!
ERROR: modpost: "__SCK__kvm_x86_get_cs_db_l_bits" [arch/x86/kvm/kvm-intel.ko] undefined!
ERROR: modpost: "__SCK__kvm_x86_cache_reg" [arch/x86/kvm/kvm-amd.ko] undefined!
ERROR: modpost: "__SCK__kvm_x86_get_cs_db_l_bits" [arch/x86/kvm/kvm-amd.ko] undefined!

Ahh, it requires using static_call_mod.

Argh, and it's actually broken for PPC32, which selects HAVE_STATIC_CALL_INLINE
but doesn't provide ARCH_ADD_TRAMP_KEY.

> Specifically, the former allows modules to do static_call_update(),
> while the latter does not. Whenever possible use the TRAMP thing, this
> allows modules to *call* the static_call, but not to redirect it.

Hmm, should we kill off EXPORT_STATIC_CALL{,_GPL}() entirely and figure out a way
to fold them into EXPORT_TRACEPOINT_SYMBOL{,_GPL}()? Or create macros that are
quite cleary only for tracepoints. KVM x86 is the only other user, and all of
KVM's usage is unnecessary, KVM just wants to let vendor modules invoke the call.

$ git grep EXPORT_STATIC_CALL_GPL
arch/x86/kvm/pmu.c:EXPORT_STATIC_CALL_GPL(kvm_x86_pmu_pmc_is_disabled_in_current_mode);
arch/x86/kvm/x86.c:EXPORT_STATIC_CALL_GPL(kvm_x86_get_cs_db_l_bits);
arch/x86/kvm/x86.c:EXPORT_STATIC_CALL_GPL(kvm_x86_cache_reg);
arch/x86/kvm/x86.c:EXPORT_STATIC_CALL_GPL(kvm_x86_get_cpl);
include/linux/static_call.h:#define EXPORT_STATIC_CALL_GPL(name) \
include/linux/static_call.h:#define EXPORT_STATIC_CALL_GPL(name) \
include/linux/static_call.h:#define EXPORT_STATIC_CALL_GPL(name) EXPORT_SYMBOL_GPL(STATIC_CALL_KEY(name))
include/linux/tracepoint.h: EXPORT_STATIC_CALL_GPL(tp_func_##name)

$ git grep -w EXPORT_STATIC_CALL
include/linux/static_call.h: * EXPORT_STATIC_CALL{,_TRAMP}{,_GPL}()
include/linux/static_call.h: * EXPORT_STATIC_CALL() vs EXPORT_STATIC_CALL_TRAMP():
include/linux/static_call.h:#define EXPORT_STATIC_CALL(name) \
include/linux/static_call.h:#define EXPORT_STATIC_CALL(name) \
include/linux/static_call.h:#define EXPORT_STATIC_CALL(name) EXPORT_SYMBOL(STATIC_CALL_KEY(name))
include/linux/tracepoint.h: EXPORT_STATIC_CALL(tp_func_##name)

As for KVM, if we're going to hack on the static call exports, this would be a
good time to add EXPORT_STATIC_CALL_FOR_KVM{,_INTERNAL}.

The attached patches appear to do what I want, and pass my build tests. If they
seem reasonable (I would say "sane", but none of this is sane :-D), I'll write
changelogs and post them.