KVM: x86: Move CPUID 0xD.1 handling out of the index>0 loop
authorSean Christopherson <sean.j.christopherson@intel.com>
Mon, 2 Mar 2020 23:56:09 +0000 (15:56 -0800)
committerPaolo Bonzini <pbonzini@redhat.com>
Mon, 16 Mar 2020 16:57:58 +0000 (17:57 +0100)
Mov the sub-leaf 1 handling for CPUID 0xD out of the index>0 loop so
that the loop only handles index>2.  Sub-leafs 2+ have identical
semantics, whereas sub-leaf 1 is effectively a feature sub-leaf.

Moving sub-leaf 1 out of the loop does duplicate a bit of code, but
the nent/maxnent code will be consolidated in a future patch, and
duplicating the clear of ECX/EDX is arguably a good thing as the reasons
for clearing said registers are completely different.

No functional change intended.

Reviewed-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/cpuid.c

index e5cf1e0..fc85405 100644 (file)
@@ -653,26 +653,33 @@ static inline int __do_cpuid_func(struct kvm_cpuid_entry2 *entry, u32 function,
                if (!supported)
                        break;
 
-               for (idx = 1, i = 1; idx < 64; ++idx) {
+               if (*nent >= maxnent)
+                       goto out;
+
+               do_host_cpuid(&entry[1], function, 1);
+               ++*nent;
+
+               entry[1].eax &= kvm_cpuid_D_1_eax_x86_features;
+               cpuid_mask(&entry[1].eax, CPUID_D_1_EAX);
+               if (entry[1].eax & (F(XSAVES)|F(XSAVEC)))
+                       entry[1].ebx = xstate_required_size(supported, true);
+               else
+                       entry[1].ebx = 0;
+               /* Saving XSS controlled state via XSAVES isn't supported. */
+               entry[1].ecx = 0;
+               entry[1].edx = 0;
+
+               for (idx = 2, i = 2; idx < 64; ++idx) {
                        u64 mask = ((u64)1 << idx);
+
                        if (*nent >= maxnent)
                                goto out;
 
                        do_host_cpuid(&entry[i], function, idx);
-                       if (idx == 1) {
-                               entry[i].eax &= kvm_cpuid_D_1_eax_x86_features;
-                               cpuid_mask(&entry[i].eax, CPUID_D_1_EAX);
-                               entry[i].ebx = 0;
-                               if (entry[i].eax & (F(XSAVES)|F(XSAVEC)))
-                                       entry[i].ebx =
-                                               xstate_required_size(supported,
-                                                                    true);
-                       } else {
-                               if (entry[i].eax == 0 || !(supported & mask))
-                                       continue;
-                               if (WARN_ON_ONCE(entry[i].ecx & 1))
-                                       continue;
-                       }
+                       if (entry[i].eax == 0 || !(supported & mask))
+                               continue;
+                       if (WARN_ON_ONCE(entry[i].ecx & 1))
+                               continue;
                        entry[i].ecx = 0;
                        entry[i].edx = 0;
                        ++*nent;