@@ -4959,12 +4959,6 @@ struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
best = e;
break;
}
- /*
- * Both basic or both extended?
- */
- if (((e->function ^ function) & 0x80000000) == 0)
- if (!best || e->function > best->function)
- best = e;
}
return best;
}
@@ -4996,6 +4990,19 @@ void kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
kvm_register_write(vcpu, VCPU_REGS_RCX, 0);
kvm_register_write(vcpu, VCPU_REGS_RDX, 0);
best = kvm_find_cpuid_entry(vcpu, function, index);
+
+ /* if no match is found, check whether we exceed the vCPU's limit
+ * and return the content of the highest valid standard leaf instead.
+ * This is to satisfy the CPUID specification.
+ */
+ if (!best) {
+ best = kvm_find_cpuid_entry(vcpu, function & 0x80000000, 0);
+ if (best && best->eax < function)
+ best = kvm_find_cpuid_entry(vcpu, best->eax, index);
+ else
+ best = NULL;
+ }
+
if (best) {
kvm_register_write(vcpu, VCPU_REGS_RAX, best->eax);
kvm_register_write(vcpu, VCPU_REGS_RBX, best->ebx);