On Wed, May 13, 2026 at 3:46 PM Jim Mattson <[email protected]> wrote:
>
> On AMD CPUs, CPUID faulting support is advertised via
> CPUID.80000021H:EAX.CpuidUserDis[bit 17] and enabled by setting
> HWCR.CpuidUserDis[bit 35].
>
> Advertise the feature to userspace regardless of host CPU support. Allow
> writes to HWCR to set bit 35 when the guest CPUID advertises
> CpuidUserDis. Update cpuid_fault_enabled() to check HWCR.CpuidUserDis
> as well as MSR_FEATURE_ENABLES.CPUID_GP_ON_CPL_GT_0.
>
> Signed-off-by: Jim Mattson <[email protected]>
> ---
>  arch/x86/include/asm/msr-index.h |  1 +
>  arch/x86/kvm/cpuid.c             |  2 +-
>  arch/x86/kvm/cpuid.h             |  5 +++--
>  arch/x86/kvm/x86.c               | 18 ++++++++++++------
>  4 files changed, 17 insertions(+), 9 deletions(-)
>
> diff --git a/arch/x86/include/asm/msr-index.h 
> b/arch/x86/include/asm/msr-index.h
> index 6673601246b3..0eeae121b0a6 100644
> --- a/arch/x86/include/asm/msr-index.h
> +++ b/arch/x86/include/asm/msr-index.h
> @@ -888,6 +888,7 @@
>  #define MSR_K7_HWCR_IRPERF_EN_BIT      30
>  #define MSR_K7_HWCR_IRPERF_EN          BIT_ULL(MSR_K7_HWCR_IRPERF_EN_BIT)
>  #define MSR_K7_HWCR_CPUID_USER_DIS_BIT 35
> +#define MSR_K7_HWCR_CPUID_USER_DIS     
> BIT_ULL(MSR_K7_HWCR_CPUID_USER_DIS_BIT)
>  #define MSR_K7_FID_VID_CTL             0xc0010041
>  #define MSR_K7_FID_VID_STATUS          0xc0010042
>  #define MSR_K7_HWCR_CPB_DIS_BIT                25
> diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
> index 1c95d1fa3ead..8e5340dd2621 100644
> --- a/arch/x86/kvm/cpuid.c
> +++ b/arch/x86/kvm/cpuid.c
> @@ -1248,7 +1248,7 @@ void kvm_initialize_cpu_caps(void)
>                 F(AUTOIBRS),
>                 EMULATED_F(NO_SMM_CTL_MSR),
>                 /* PrefetchCtlMsr */
> -               /* GpOnUserCpuid */
> +               EMULATED_F(GP_ON_USER_CPUID),
>                 /* EPSF */
>                 F(PREFETCHI),
>                 F(AVX512_BMM),
> diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
> index 95d09ccbf951..fc96ba86c644 100644
> --- a/arch/x86/kvm/cpuid.h
> +++ b/arch/x86/kvm/cpuid.h
> @@ -185,8 +185,9 @@ static inline int guest_cpuid_stepping(struct kvm_vcpu 
> *vcpu)
>
>  static inline bool cpuid_fault_enabled(struct kvm_vcpu *vcpu)
>  {
> -       return vcpu->arch.msr_misc_features_enables &
> -                 MSR_MISC_FEATURES_ENABLES_CPUID_FAULT;
> +       return (vcpu->arch.msr_misc_features_enables &
> +               MSR_MISC_FEATURES_ENABLES_CPUID_FAULT) ||
> +               (vcpu->arch.msr_hwcr & MSR_K7_HWCR_CPUID_USER_DIS);
>  }

Sashiko raises a good point here about a pre-existing issue that
probably warrants a fix before propagating it further:

> Does this emulation of CPUID faulting respect architectural fault priorities 
> in a nested virtualization scenario?
> According to the AMD APM, if CPUID faulting is enabled, a #GP fault takes 
> precedence over a CPUID VM-exit intercept.
> Because KVM emulates CPUID faulting in kvm_emulate_cpuid(), the fault check 
> happens after nested VM-exit intercept checks. If an L1 hypervisor enables 
> both CPUID faulting and a CPUID VM-exit intercept, L0's nested exit handlers 
> will observe L1's intercept request and immediately reflect the VM-exit to L1.
> Since this reflection happens before evaluating kvm_emulate_cpuid(), does 
> this allow L2 guests to completely bypass the CPUID faulting restrictions 
> imposed by L1?

Reply via email to