@@ -58,25 +58,24 @@ void __init kvm_init_xstate_sizes(void)
5858
5959u32 xstate_required_size (u64 xstate_bv , bool compacted )
6060{
61- int feature_bit = 0 ;
6261 u32 ret = XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET ;
62+ int i ;
6363
6464 xstate_bv &= XFEATURE_MASK_EXTEND ;
65- while (xstate_bv ) {
66- if (xstate_bv & 0x1 ) {
67- struct cpuid_xstate_sizes * xs = & xstate_sizes [feature_bit ];
68- u32 offset ;
69-
70- /* ECX[1]: 64B alignment in compacted form */
71- if (compacted )
72- offset = (xs -> ecx & 0x2 ) ? ALIGN (ret , 64 ) : ret ;
73- else
74- offset = xs -> ebx ;
75- ret = max (ret , offset + xs -> eax );
76- }
65+ for (i = XFEATURE_YMM ; i < ARRAY_SIZE (xstate_sizes ) && xstate_bv ; i ++ ) {
66+ struct cpuid_xstate_sizes * xs = & xstate_sizes [i ];
67+ u32 offset ;
68+
69+ if (!(xstate_bv & BIT_ULL (i )))
70+ continue ;
7771
78- xstate_bv >>= 1 ;
79- feature_bit ++ ;
72+ /* ECX[1]: 64B alignment in compacted form */
73+ if (compacted )
74+ offset = (xs -> ecx & 0x2 ) ? ALIGN (ret , 64 ) : ret ;
75+ else
76+ offset = xs -> ebx ;
77+ ret = max (ret , offset + xs -> eax );
78+ xstate_bv &= ~BIT_ULL (i );
8079 }
8180
8281 return ret ;
@@ -196,6 +195,7 @@ static int kvm_check_cpuid(struct kvm_vcpu *vcpu)
196195}
197196
198197static u32 kvm_apply_cpuid_pv_features_quirk (struct kvm_vcpu * vcpu );
198+ static void kvm_update_cpuid_runtime (struct kvm_vcpu * vcpu );
199199
200200/* Check whether the supplied CPUID data is equal to what is already set for the vCPU. */
201201static int kvm_cpuid_check_equal (struct kvm_vcpu * vcpu , struct kvm_cpuid_entry2 * e2 ,
@@ -300,10 +300,12 @@ static __always_inline void kvm_update_feature_runtime(struct kvm_vcpu *vcpu,
300300 guest_cpu_cap_change (vcpu , x86_feature , has_feature );
301301}
302302
303- void kvm_update_cpuid_runtime (struct kvm_vcpu * vcpu )
303+ static void kvm_update_cpuid_runtime (struct kvm_vcpu * vcpu )
304304{
305305 struct kvm_cpuid_entry2 * best ;
306306
307+ vcpu -> arch .cpuid_dynamic_bits_dirty = false;
308+
307309 best = kvm_find_cpuid_entry (vcpu , 1 );
308310 if (best ) {
309311 kvm_update_feature_runtime (vcpu , best , X86_FEATURE_OSXSAVE ,
@@ -333,7 +335,6 @@ void kvm_update_cpuid_runtime(struct kvm_vcpu *vcpu)
333335 cpuid_entry_has (best , X86_FEATURE_XSAVEC )))
334336 best -> ebx = xstate_required_size (vcpu -> arch .xcr0 , true);
335337}
336- EXPORT_SYMBOL_GPL (kvm_update_cpuid_runtime );
337338
338339static bool kvm_cpuid_has_hyperv (struct kvm_vcpu * vcpu )
339340{
@@ -646,6 +647,9 @@ int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
646647 if (cpuid -> nent < vcpu -> arch .cpuid_nent )
647648 return - E2BIG ;
648649
650+ if (vcpu -> arch .cpuid_dynamic_bits_dirty )
651+ kvm_update_cpuid_runtime (vcpu );
652+
649653 if (copy_to_user (entries , vcpu -> arch .cpuid_entries ,
650654 vcpu -> arch .cpuid_nent * sizeof (struct kvm_cpuid_entry2 )))
651655 return - EFAULT ;
@@ -1704,7 +1708,7 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
17041708 phys_as = entry -> eax & 0xff ;
17051709 g_phys_as = phys_as ;
17061710 if (kvm_mmu_get_max_tdp_level () < 5 )
1707- g_phys_as = min (g_phys_as , 48 );
1711+ g_phys_as = min (g_phys_as , 48U );
17081712 }
17091713
17101714 entry -> eax = phys_as | (virt_as << 8 ) | (g_phys_as << 16 );
@@ -1769,13 +1773,7 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
17691773
17701774 cpuid_entry_override (entry , CPUID_8000_0022_EAX );
17711775
1772- if (kvm_cpu_cap_has (X86_FEATURE_PERFMON_V2 ))
1773- ebx .split .num_core_pmc = kvm_pmu_cap .num_counters_gp ;
1774- else if (kvm_cpu_cap_has (X86_FEATURE_PERFCTR_CORE ))
1775- ebx .split .num_core_pmc = AMD64_NUM_COUNTERS_CORE ;
1776- else
1777- ebx .split .num_core_pmc = AMD64_NUM_COUNTERS ;
1778-
1776+ ebx .split .num_core_pmc = kvm_pmu_cap .num_counters_gp ;
17791777 entry -> ebx = ebx .full ;
17801778 break ;
17811779 }
@@ -1985,6 +1983,9 @@ bool kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx,
19851983 struct kvm_cpuid_entry2 * entry ;
19861984 bool exact , used_max_basic = false;
19871985
1986+ if (vcpu -> arch .cpuid_dynamic_bits_dirty )
1987+ kvm_update_cpuid_runtime (vcpu );
1988+
19881989 entry = kvm_find_cpuid_entry_index (vcpu , function , index );
19891990 exact = !!entry ;
19901991
@@ -2000,7 +2001,8 @@ bool kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx,
20002001 * edx = entry -> edx ;
20012002 if (function == 7 && index == 0 ) {
20022003 u64 data ;
2003- if (!__kvm_get_msr (vcpu , MSR_IA32_TSX_CTRL , & data , true) &&
2004+ if ((* ebx & (feature_bit (RTM ) | feature_bit (HLE ))) &&
2005+ !__kvm_get_msr (vcpu , MSR_IA32_TSX_CTRL , & data , true) &&
20042006 (data & TSX_CTRL_CPUID_CLEAR ))
20052007 * ebx &= ~(feature_bit (RTM ) | feature_bit (HLE ));
20062008 } else if (function == 0x80000007 ) {
0 commit comments