diff options
author | Jim Mattson <jmattson@google.com> | 2019-09-25 14:17:14 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2019-09-26 06:31:30 -0400 |
commit | a1a640b8c0cd8a2a7f84ab694f04bc64dc6988af (patch) | |
tree | 369893c787df8ebb498a44ef98cb7f570c2d4dab | |
parent | a0f0037e908c656573d165aadbfae6c05fc4dd75 (diff) |
kvm: x86: Fix a spurious -E2BIG in __do_cpuid_func
Don't return -E2BIG from __do_cpuid_func when processing function 0BH
or 1FH and the last interesting subleaf occupies the last allocated
entry in the result array.
Cc: Paolo Bonzini <pbonzini@redhat.com>
Fixes: 831bf664e9c1fc ("KVM: Refactor and simplify kvm_dev_ioctl_get_supported_cpuid")
Signed-off-by: Jim Mattson <jmattson@google.com>
Reviewed-by: Peter Shier <pshier@google.com>
Reviewed-by: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | arch/x86/kvm/cpuid.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 63316036f85a..6bf4a261b308 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c | |||
@@ -618,16 +618,20 @@ static inline int __do_cpuid_func(struct kvm_cpuid_entry2 *entry, u32 function, | |||
618 | */ | 618 | */ |
619 | case 0x1f: | 619 | case 0x1f: |
620 | case 0xb: { | 620 | case 0xb: { |
621 | int i, level_type; | 621 | int i; |
622 | 622 | ||
623 | /* read more entries until level_type is zero */ | 623 | /* |
624 | for (i = 1; ; ++i) { | 624 | * We filled in entry[0] for CPUID(EAX=<function>, |
625 | * ECX=00H) above. If its level type (ECX[15:8]) is | ||
626 | * zero, then the leaf is unimplemented, and we're | ||
627 | * done. Otherwise, continue to populate entries | ||
628 | * until the level type (ECX[15:8]) of the previously | ||
629 | * added entry is zero. | ||
630 | */ | ||
631 | for (i = 1; entry[i - 1].ecx & 0xff00; ++i) { | ||
625 | if (*nent >= maxnent) | 632 | if (*nent >= maxnent) |
626 | goto out; | 633 | goto out; |
627 | 634 | ||
628 | level_type = entry[i - 1].ecx & 0xff00; | ||
629 | if (!level_type) | ||
630 | break; | ||
631 | do_host_cpuid(&entry[i], function, i); | 635 | do_host_cpuid(&entry[i], function, i); |
632 | ++*nent; | 636 | ++*nent; |
633 | } | 637 | } |