Fix MSR emulation to hide Intel functionality that we don't support
authorGan Shun <ganshun@gmail.com>
Thu, 4 Aug 2016 17:45:15 +0000 (10:45 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 4 Aug 2016 18:00:43 +0000 (11:00 -0700)
We report 0 for perf capabilities because we don't want to support perf
tools yet, and we report 0 for MCG to prevent linux from trying to setup
machine checks.

Signed-off-by: Gan Shun <ganshun@gmail.com>
Change-Id: Ieef80e16536a8448a570b69342e4a58ef82b15f0
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/arch/x86/trap.c
kern/arch/x86/vmm/vmm.c

index 949d3a1..83ad353 100644 (file)
@@ -880,26 +880,33 @@ static bool handle_vmexit_cpuid(struct vm_trapframe *tf)
 {
        uint32_t eax, ebx, ecx, edx;
 
-       /* 0x4000000 is taken from Linux; it is not documented but it signals the
-        * use of KVM. */
-       if (tf->tf_rax == 0x40000000) {
-               /* Pretend to be KVM: Return the KVM signature by placing the following
-                * constants in RAX, RBX, RCX and RDX. RAX is set to 0, while RBX to
-                * RDX forms the string "KVMKVMKVMKVM\0\0\0". This can be placed in
-                * 0x100 offsets from 0x40000000 to 0x40010000. */
-               eax = 0;
-               ebx = 0x4b4d564b;
-               ecx = 0x564b4d56;
-               edx = 0x0000004d;
-       } else {
-               cpuid(tf->tf_rax, tf->tf_rcx, &eax, &ebx, &ecx, &edx);
-               if (tf->tf_rax == 1) {
+       cpuid(tf->tf_rax, tf->tf_rcx, &eax, &ebx, &ecx, &edx);
+       switch (tf->tf_rax) {
+               case 0x01:
                        /* Set the hypervisor bit to let the guest know it is virtualized */
                        ecx |= 1 << 31;
                        /* Unset the vmx capability bit so that the guest does not try
                         * to turn it on. */
                        ecx &= ~(1 << 5);
-               }
+                       /* Unset the perf capability bit so that the guest does not try
+                        * to turn it on. */
+                       ecx &= ~(1 << 15);
+                       break;
+               case 0x0A:
+                       eax = 0;
+                       ebx = 0;
+                       ecx = 0;
+                       edx = 0;
+                       break;
+               /* Signal the use of KVM. */
+               case 0x40000000:
+                       eax = 0;
+                       ebx = 0x4b4d564b;
+                       ecx = 0x564b4d56;
+                       edx = 0x0000004d;
+                       break;
+               default:
+                       break;
        }
        tf->tf_rax = eax;
        tf->tf_rbx = ebx;
index 072f320..c0172d6 100644 (file)
@@ -268,14 +268,16 @@ struct emmsr emmsrs[] = {
        {MSR_PEBS_LD_LAT_THRESHOLD, "MSR_PEBS_LD_LAT_THRESHOLD", emsr_ok},
        // aaaaaahhhhhhhhhhhhhhhhhhhhh
        {MSR_ARCH_PERFMON_EVENTSEL0, "MSR_ARCH_PERFMON_EVENTSEL0", emsr_ok},
-       {MSR_ARCH_PERFMON_EVENTSEL1, "MSR_ARCH_PERFMON_EVENTSEL0", emsr_ok},
-       {MSR_IA32_PERF_CAPABILITIES, "MSR_IA32_PERF_CAPABILITIES", emsr_ok},
+       {MSR_ARCH_PERFMON_EVENTSEL1, "MSR_ARCH_PERFMON_EVENTSEL1", emsr_ok},
+       {MSR_IA32_PERF_CAPABILITIES, "MSR_IA32_PERF_CAPABILITIES", emsr_readzero},
        // unsafe.
        {MSR_IA32_APICBASE, "MSR_IA32_APICBASE", emsr_fake_apicbase},
 
        // mostly harmless.
        {MSR_TSC_AUX, "MSR_TSC_AUX", emsr_fakewrite},
        {MSR_RAPL_POWER_UNIT, "MSR_RAPL_POWER_UNIT", emsr_readzero},
+       {MSR_IA32_MCG_CAP, "MSR_IA32_MCG_CAP", emsr_readzero},
+       {MSR_IA32_DEBUGCTLMSR, "MSR_IA32_DEBUGCTLMSR", emsr_fakewrite},
 
        // TBD
        {MSR_IA32_TSC_DEADLINE, "MSR_IA32_TSC_DEADLINE", emsr_fakewrite},