From: Paolo Bonzini pbonzini@redhat.com
mainline inclusion from mainline-v5.3-rc1 commit d9aadaf689928ba896529cb684729923b21c2de5 category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I3YAEG CVE: NA
-----------------------------
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 Signed-off-by: Jingyi Wang wangjingyi11@huawei.com Reviewed-by: Keqian Zhu zhukeqian1@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- arch/x86/kvm/cpuid.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-)
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 38a0e3b66079a..5ff8cb246b007 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -291,6 +291,18 @@ 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: + entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX; + break; + } }
static int __do_cpuid_func_emulated(struct kvm_cpuid_entry2 *entry, @@ -494,14 +506,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; @@ -510,7 +520,6 @@ static inline int __do_cpuid_func(struct kvm_cpuid_entry2 *entry, u32 function, case 4: { 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) @@ -520,8 +529,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; @@ -536,7 +543,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) @@ -546,8 +552,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; @@ -587,7 +591,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) @@ -597,8 +600,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; @@ -611,7 +612,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;
@@ -637,8 +637,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; }