TritonDataCenter / illumos-kvm

KVM driver for illumos
Other
116 stars 65 forks source link

cpuid should indicate that it's being run under KVM #21

Open rmustacc opened 9 years ago

rmustacc commented 9 years ago

There's a region of CPUID reserved for hypervisors and one of those CPUID entries is in identification. We should probably follow KVM's lead here of KVMKVMKVM, though we could also use our own identifier instead.

ajacoutot commented 9 years ago

There may be code out-there that already checks for the 'KVMKVMKVM' string so if we follow the same naming, that means no other change should be required.

s-fritsch commented 9 years ago

If you use 'KVMKVMKVM\0\0\0' you should also support the cpuid page with the KVM feature flags. This is probably a good idea because of your Linux-KVM heritage, it may well be possible that you support some of these features in the future. For now, just set all flags to zero. See Documentation/virtual/kvm/cpuid.txt in the linux source.

Apart from that, it is possible to have more than one hypervisor signature cpuid page. Linux looks for hypervisor signatures between 0x40000000 and 0x40010000 in steps of 0x100. Therefore I would recommend that you add an illumos-kvm specific signature, too.

You could even add a Hyper-V signature page in addition to that, and use it to announce support for the Hyper-V APIC-MSRs. You have inherited support for these from Linux-KVM. Since the patch I did for openbsd and that Antoine tested on illumos-kvm uses those MSRs to improve performance quite a bit, having the support announced explicitly would make the detection easier. You can see code to set up the Hyper-V signature and feature cpuid pages in current qemu. Or look it up in the Hyper-V spec.

aszeszo commented 9 years ago

Plesk is an example of software that checks cpuid to determine if you are entitled to use "virtual server" license, which is cheaper vs. "dedicated server" one. I have applied the changes below to make it recognise SmartOS KVM VM as "kvm" platform. I did try enabling feature flags but Ubuntu's kernel didn't seem to like them much.

[smartos@komatsu ~/smartos-live/projects/local/kvm-cmd]$ git diff target-i386/kvm.c
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index ee5fc13..4262b92 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -38,6 +38,7 @@
 #ifdef CONFIG_KVM_PARA
 #include <linux/kvm_para.h>
 #endif
+#define KVM_CPUID_SIGNATURE    0x40000000

 #ifdef __sun__
 #define        __u64   uint64_t
@@ -325,9 +326,7 @@ int kvm_arch_init_vcpu(CPUState *env)
     uint32_t limit, i, j, cpuid_i;
     uint32_t unused;
     struct kvm_cpuid_entry2 *c;
-#ifdef CONFIG_KVM_PARA
     uint32_t signature[3];
-#endif

     r = _kvm_arch_init_vcpu(env);
     if (r < 0) {
@@ -350,7 +349,6 @@ int kvm_arch_init_vcpu(CPUState *env)

     cpuid_i = 0;

-#ifdef CONFIG_KVM_PARA
     /* Paravirtualization CPUIDs */
     memcpy(signature, "KVMKVMKVM\0\0\0", 12);
     c = &cpuid_data.entries[cpuid_i++];
@@ -361,6 +359,7 @@ int kvm_arch_init_vcpu(CPUState *env)
     c->ecx = signature[1];
     c->edx = signature[2];

+#ifdef CONFIG_KVM_PARA
     c = &cpuid_data.entries[cpuid_i++];
     memset(c, 0, sizeof(*c));
     c->function = KVM_CPUID_FEATURES;
[smartos@komatsu ~/smartos-live/projects/local/kvm-cmd]$