Re: [PATCH v2 19/49] KVM: x86: Add a macro to init CPUID features that ignore host kernel support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 2024-05-17 at 10:38 -0700, Sean Christopherson wrote:
> Add a macro for use in kvm_set_cpu_caps() to automagically initialize
> features that KVM wants to support based solely on the CPU's capabilities,
> e.g. KVM advertises LA57 support if it's available in hardware, even if
> the host kernel isn't utilizing 57-bit virtual addresses.
> 
> Take advantage of the fact that kvm_cpu_cap_mask() adjusts kvm_cpu_caps
> based on raw CPUID, i.e. will clear features bits that aren't supported in
> hardware, and simply force-set the capability before applying the mask.
> 
> Abusing kvm_cpu_cap_set() is a borderline evil shenanigan, but doing so
> avoid extra CPUID lookups, and a future commit will harden the entire
> family of *F() macros to assert (at compile time) that every feature being
> allowed is part of the capability word being processed, i.e. using a macro
> will bring more advantages in the future.

Could you explain what do you mean by "extra CPUID lookups"?


> 
> Avoiding CPUID also fixes a largely benign bug where KVM could incorrectly
> report LA57 support on Intel CPUs whose max supported CPUID is less than 7,
> i.e. if the max supported leaf (<7) happened to have bit 16 set.  In
> practice, barring a funky virtual machine setup, the bug is benign as all
> known CPUs that support VMX also support leaf 7.
> 
> Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx>
> ---
>  arch/x86/kvm/cpuid.c | 17 +++++++++++++----
>  1 file changed, 13 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
> index 77625a5477b1..a802c09b50ab 100644
> --- a/arch/x86/kvm/cpuid.c
> +++ b/arch/x86/kvm/cpuid.c
> @@ -70,6 +70,18 @@ u32 xstate_required_size(u64 xstate_bv, bool compacted)
>  	(boot_cpu_has(X86_FEATURE_##name) ? F(name) : 0);	\
>  })
>  
> +/*
> + * Raw Feature - For features that KVM supports based purely on raw host CPUID,
> + * i.e. that KVM virtualizes even if the host kernel doesn't use the feature.
> + * Simply force set the feature in KVM's capabilities, raw CPUID support will
> + * be factored in by kvm_cpu_cap_mask().
> + */
> +#define RAW_F(name)						\
> +({								\
> +	kvm_cpu_cap_set(X86_FEATURE_##name);			\
> +	F(name);						\
> +})
> +
>  /*
>   * Magic value used by KVM when querying userspace-provided CPUID entries and
>   * doesn't care about the CPIUD index because the index of the function in
> @@ -682,15 +694,12 @@ void kvm_set_cpu_caps(void)
>  		F(AVX512VL));
>  
>  	kvm_cpu_cap_mask(CPUID_7_ECX,
> -		F(AVX512VBMI) | F(LA57) | F(PKU) | 0 /*OSPKE*/ | F(RDPID) |
> +		F(AVX512VBMI) | RAW_F(LA57) | F(PKU) | 0 /*OSPKE*/ | F(RDPID) |
>  		F(AVX512_VPOPCNTDQ) | F(UMIP) | F(AVX512_VBMI2) | F(GFNI) |
>  		F(VAES) | F(VPCLMULQDQ) | F(AVX512_VNNI) | F(AVX512_BITALG) |
>  		F(CLDEMOTE) | F(MOVDIRI) | F(MOVDIR64B) | 0 /*WAITPKG*/ |
>  		F(SGX_LC) | F(BUS_LOCK_DETECT)
>  	);
> -	/* Set LA57 based on hardware capability. */
> -	if (cpuid_ecx(7) & F(LA57))
> -		kvm_cpu_cap_set(X86_FEATURE_LA57);
>  
>  	/*
>  	 * PKU not yet implemented for shadow paging and requires OSPKE

Putting a function call into a macro which evaluates into a bitmask is somewhat misleading,
but let it be...

IMHO in long term, it might be better to rip the whole huge 'or'ed mess, and replace
it with a list of statements, along with comments for all unusual cases.


Reviewed-by: Maxim Levitsky <mlevitsk@xxxxxxxxxx>

Best regards,
	Maxim Levitsky







[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux