OSDN Git Service

KVM: cpuid: set struct kvm_cpuid_entry2 flags in do_cpuid_1_ent
authorPaolo Bonzini <pbonzini@redhat.com>
Thu, 4 Jul 2019 10:20:48 +0000 (12:20 +0200)
committerPaolo Bonzini <pbonzini@redhat.com>
Fri, 5 Jul 2019 11:48:44 +0000 (13:48 +0200)
do_cpuid_1_ent is typically called in two places by __do_cpuid_func
for CPUID functions that have subleafs.  Both places have to set
the KVM_CPUID_FLAG_SIGNIFCANT_INDEX.  Set that flag, and
KVM_CPUID_FLAG_STATEFUL_FUNC as well, directly in do_cpuid_1_ent.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/cpuid.c

index 2e852a8..a46e882 100644 (file)
@@ -298,6 +298,20 @@ static void do_cpuid_1_ent(struct kvm_cpuid_entry2 *entry, u32 function,
 
        cpuid_count(entry->function, entry->index,
                    &entry->eax, &entry->ebx, &entry->ecx, &entry->edx);
+
+       switch (function) {
+       case 2:
+               entry->flags |= KVM_CPUID_FLAG_STATEFUL_FUNC;
+               break;
+       case 4:
+       case 7:
+       case 0xb:
+       case 0xd:
+       case 0x14:
+       case 0x8000001d:
+               entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
+               break;
+       }
 }
 
 static int __do_cpuid_func_emulated(struct kvm_cpuid_entry2 *entry,
@@ -497,14 +511,12 @@ static inline int __do_cpuid_func(struct kvm_cpuid_entry2 *entry, u32 function,
        case 2: {
                int t, times = entry->eax & 0xff;
 
-               entry->flags |= KVM_CPUID_FLAG_STATEFUL_FUNC;
                entry->flags |= KVM_CPUID_FLAG_STATE_READ_NEXT;
                for (t = 1; t < times; ++t) {
                        if (*nent >= maxnent)
                                goto out;
 
                        do_cpuid_1_ent(&entry[t], function, 0);
-                       entry[t].flags |= KVM_CPUID_FLAG_STATEFUL_FUNC;
                        ++*nent;
                }
                break;
@@ -514,7 +526,6 @@ static inline int __do_cpuid_func(struct kvm_cpuid_entry2 *entry, u32 function,
        case 0x8000001d: {
                int i, cache_type;
 
-               entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
                /* read more entries until cache_type is zero */
                for (i = 1; ; ++i) {
                        if (*nent >= maxnent)
@@ -524,8 +535,6 @@ static inline int __do_cpuid_func(struct kvm_cpuid_entry2 *entry, u32 function,
                        if (!cache_type)
                                break;
                        do_cpuid_1_ent(&entry[i], function, i);
-                       entry[i].flags |=
-                              KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
                        ++*nent;
                }
                break;
@@ -540,7 +549,6 @@ static inline int __do_cpuid_func(struct kvm_cpuid_entry2 *entry, u32 function,
        case 7: {
                int i;
 
-               entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
                for (i = 0; ; ) {
                        do_cpuid_7_mask(&entry[i], i);
                        if (i == entry->eax)
@@ -550,8 +558,6 @@ static inline int __do_cpuid_func(struct kvm_cpuid_entry2 *entry, u32 function,
 
                        ++i;
                        do_cpuid_1_ent(&entry[i], function, i);
-                       entry[i].flags |=
-                              KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
                        ++*nent;
                }
                break;
@@ -595,7 +601,6 @@ static inline int __do_cpuid_func(struct kvm_cpuid_entry2 *entry, u32 function,
        case 0xb: {
                int i, level_type;
 
-               entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
                /* read more entries until level_type is zero */
                for (i = 1; ; ++i) {
                        if (*nent >= maxnent)
@@ -605,8 +610,6 @@ static inline int __do_cpuid_func(struct kvm_cpuid_entry2 *entry, u32 function,
                        if (!level_type)
                                break;
                        do_cpuid_1_ent(&entry[i], function, i);
-                       entry[i].flags |=
-                              KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
                        ++*nent;
                }
                break;
@@ -619,7 +622,6 @@ static inline int __do_cpuid_func(struct kvm_cpuid_entry2 *entry, u32 function,
                entry->ebx = xstate_required_size(supported, false);
                entry->ecx = entry->ebx;
                entry->edx &= supported >> 32;
-               entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
                if (!supported)
                        break;
 
@@ -645,8 +647,6 @@ static inline int __do_cpuid_func(struct kvm_cpuid_entry2 *entry, u32 function,
                        }
                        entry[i].ecx = 0;
                        entry[i].edx = 0;
-                       entry[i].flags |=
-                              KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
                        ++*nent;
                        ++i;
                }
@@ -659,12 +659,10 @@ static inline int __do_cpuid_func(struct kvm_cpuid_entry2 *entry, u32 function,
                if (!f_intel_pt)
                        break;
 
-               entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
                for (t = 1; t <= times; ++t) {
                        if (*nent >= maxnent)
                                goto out;
                        do_cpuid_1_ent(&entry[t], function, t);
-                       entry[t].flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
                        ++*nent;
                }
                break;