@@ -274,6 +274,7 @@ int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
if (copy_to_user(entries, &vcpu->arch.cpuid_entries,
vcpu->arch.cpuid_nent * sizeof(struct kvm_cpuid_entry2)))
goto out;
+ cpuid->nent = vcpu->arch.cpuid_nent;
return 0;
out:
@@ -4161,12 +4161,12 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
goto out;
r = kvm_vcpu_ioctl_get_cpuid2(vcpu, &cpuid,
cpuid_arg->entries);
- if (r)
+ if (r && r != -E2BIG)
goto out;
- r = -EFAULT;
- if (copy_to_user(cpuid_arg, &cpuid, sizeof(cpuid)))
+ if (copy_to_user(cpuid_arg, &cpuid, sizeof(cpuid))) {
+ r = -EFAULT;
goto out;
- r = 0;
+ }
break;
}
case KVM_GET_MSRS: {
KVM_GET_CPUID2 never indicates the array length it populates. If an app passes in an array that's too short then kvm_vcpu_ioctl_get_cpuid2() populates the required array length and returns -E2BIG. However, its caller then just bails to "goto out", thus bypassing the copy_to_user(). If an app passes in an array that's not too short, then kvm_vcpu_ioctl_get_cpuid2() doesn't populate the array length. Its caller will then call copy_to_user(), which is pointless since no data values have been changed. This change attempts to have KVM_GET_CPUID2 populate the array length on both success and failure, and still indicate -E2BIG when a provided array is too short. I'm not sure if this type of change is considered an API breakage and thus we need a KVM_GET_CPUID3. Fixes: 0771671749b59 ("KVM: Enhance guest cpuid management", 2007-11-21) Signed-off-by: Matt Delco <delco@chromium.org> --- arch/x86/kvm/cpuid.c | 1 + arch/x86/kvm/x86.c | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-)