Page MenuHomeFreeBSD

Add a workaround to the hypervisor detection for older versions of KVM.

Authored by jhb on Mar 23 2018, 9:10 PM.



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.

Test Plan
  • 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

rS FreeBSD src repository
Automatic diff as part of commit; lint not applicable.
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

jhb created this revision.Mar 23 2018, 9:10 PM
jhb updated this revision to Diff 40653.Mar 23 2018, 9:14 PM
  • Make this workaround narrower and more KVM-specific.
jhb added a subscriber: jpaetzel.Mar 23 2018, 9:14 PM

Josh, can you retest the updated patch?

kib accepted this revision.Mar 23 2018, 9:29 PM
This revision is now accepted and ready to land.Mar 23 2018, 9:29 PM

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.

Confirmed the new patch works.

avg added a subscriber: avg.Mar 23 2018, 9:53 PM
jhb added a comment.Mar 23 2018, 10:23 PM

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
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.

This revision was automatically updated to reflect the committed changes.
avg added a comment.Mar 24 2018, 8:34 AM
In D14810#311577, @jhb wrote:

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.