]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
kvm: Clear performance monitoring CPUID flags
authorPekka Enberg <penberg@cs.helsinki.fi>
Thu, 15 Jul 2010 14:53:58 +0000 (17:53 +0300)
committerPekka Enberg <penberg@cs.helsinki.fi>
Thu, 15 Jul 2010 15:03:50 +0000 (18:03 +0300)
Commit 3d446cf17faefd621c0842b58c92a50bd307eec7 ("kvm__setup_cpuid: use
KVM_GET_SUPPORTED_CPUID to simplify cpuid setup") causes the following errors
to be printed on host kernel dmesg:

[  775.134693] kvm: 2882: cpu0 unhandled rdmsr: 0x345
[  775.143130] kvm: 2882: cpu0 unhandled wrmsr: 0x40 data 0
[  775.143136] kvm: 2882: cpu0 unhandled wrmsr: 0x60 data 0
[  775.143141] kvm: 2882: cpu0 unhandled wrmsr: 0x41 data 0
[  775.143146] kvm: 2882: cpu0 unhandled wrmsr: 0x61 data 0
[  775.143150] kvm: 2882: cpu0 unhandled wrmsr: 0x42 data 0
[  775.143155] kvm: 2882: cpu0 unhandled wrmsr: 0x62 data 0
[  775.143159] kvm: 2882: cpu0 unhandled wrmsr: 0x43 data 0
[  775.143164] kvm: 2882: cpu0 unhandled wrmsr: 0x63 data 0

As explained by Cyrill Gorcunov, these MSR accesses come from Linux performance
events subsystems which is not supported by our little hypervisor. Therefore,
clear the performance monitoring CPUID flags to let guest kernels know about
that.

Signed-off-by: Pekka Enberg <penberg@cs.helsinki.fi>
tools/kvm/cpuid.c

index 9119855b36466ad4b96b726875278e780dd96661..f7cc930909d25221e064b8dd67536b1cbc22a786 100644 (file)
@@ -5,8 +5,31 @@
 #include <stdlib.h>
 #include <assert.h>
 
+#define CPUID_FUNC_PERFMON             0x0A
+
 #define        MAX_KVM_CPUID_ENTRIES           100
 
+static void filter_cpuid(struct kvm_cpuid2 *kvm_cpuid)
+{
+       unsigned int i;
+
+       /*
+        * Filter CPUID functions that are not supported by the hypervisor.
+        */
+       for (i = 0; i < kvm_cpuid->nent; i++) {
+               struct kvm_cpuid_entry2 *entry = &kvm_cpuid->entries[i];
+
+               switch (entry->function) {
+               case CPUID_FUNC_PERFMON:
+                       entry->eax      = 0x00; /* disable it */
+                       break;
+               default:
+                       /* Keep the CPUID function as -is */
+                       break;
+               };
+       }
+}
+
 void kvm__setup_cpuid(struct kvm *self)
 {
        struct kvm_cpuid2 *kvm_cpuid;
@@ -17,6 +40,8 @@ void kvm__setup_cpuid(struct kvm *self)
        if (ioctl(self->sys_fd, KVM_GET_SUPPORTED_CPUID, kvm_cpuid) < 0)
                die_perror("KVM_GET_SUPPORTED_CPUID failed");
 
+       filter_cpuid(kvm_cpuid);
+
        if (ioctl(self->vcpu_fd, KVM_SET_CPUID2, kvm_cpuid) < 0)
                die_perror("KVM_SET_CPUID2 failed");