Originally KVM set %eax to 0 in the cpuid leaf 0x4000000 rather than to
the highest supported leaf in the hypervisor "branch". Detect this
case and fixup the %eax value so that the hypervisor is still detected.
Details
- jpaetzel@ has a system affected by this that fails to detect the hypervisor
- FYI, this was fixed in Linux in May of 2012 by commit 57c22e5f35aa4b9b2fe11f73f3e62bbf9ef36190
Diff Detail
- Repository
- rS FreeBSD src repository - subversion
- Lint
Lint Not Applicable - Unit
Tests Not Applicable
Event Timeline
For what it's worth the system where I saw this is running the latest version of CentOS 7.4, which has an old kernel, but not that old. But just to be sure I updated it's kernel to 4.15.12 and the problem persisted. I'll test the patch though.
avg@ went so far as to verify the stock CentOS kernel included that commit you are referencing, and it does.
Hmm, the way you would tell if the kernel had the commit would be to look at the code. However, your cpuid shows it returning 0, not 0x40000001. The diff from the commit is pretty simple:
diff --git a/Documentation/virtual/kvm/cpuid.txt b/Documentation/virtual/kvm/cpu id.txt index 882068538c9c..83afe65d4966 100644 --- a/Documentation/virtual/kvm/cpuid.txt +++ b/Documentation/virtual/kvm/cpuid.txt @@ -10,11 +10,15 @@ a guest. KVM cpuid functions are: function: KVM_CPUID_SIGNATURE (0x40000000) -returns : eax = 0, +returns : eax = 0x40000001, ebx = 0x4b4d564b, ecx = 0x564b4d56, edx = 0x4d. Note that this value in ebx, ecx and edx corresponds to the string "KVMKVMKVM". +The value in eax corresponds to the maximum cpuid function present in this leaf, +and will be updated if more functions are added in the future. +Note also that old hosts set eax value to 0x0. This should +be interpreted as if the value was 0x40000001. This function queries the presence of KVM cpuid leafs. diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index c2134b881033..7df1c6d839fb 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -398,7 +398,7 @@ static int do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, case KVM_CPUID_SIGNATURE: { char signature[12] = "KVMKVMKVM\0\0"; u32 *sigptr = (u32 *)signature; - entry->eax = 0; + entry->eax = KVM_CPUID_FEATURES; entry->ebx = sigptr[0]; entry->ecx = sigptr[1]; entry->edx = sigptr[2];
The line in the kernel hasn't changed since that commit, so the only way you are getting 0 is if your kernel doesn't have the patch.
Yes, that's the only logical conclusion, but as Josh said earlier I got the source RPM for the kernel in question and the code there has the change.
kernel-3.10.0-693.21.1.el7.src.rpm is the file I examined.
Also, it's hard to believe that a kernel change from 2012 (around linux 3.5 time) wouldn't make it into CentOS 7.4 by now.
So, not sure what is happening, but getting to the bottom of it may not be worth the time required.