vmm: refactor cpuid vmexit handling (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 24 May 2019 20:53:00 +0000 (16:53 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 24 May 2019 21:31:58 +0000 (17:31 -0400)
This was a minor irritant anytime I looked at cpuid handling.  Even
though we just have one cpuid that userspace was checking, we shouldn't
have hardcoded the check.

Reinstall your kernel headers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/arch/x86/ros/vmm.h
kern/arch/x86/trap.c
user/vmm/vmexit.c

index 6d5d2f9..91f9cad 100644 (file)
@@ -23,3 +23,12 @@ struct vmm_gpcore_init {
 #define VM_TRAP_ERROR_CODE          (1 << 11)
 #define VM_TRAP_HARDWARE            (3 << 8)
 /* End Intel VM Trap Injection Fields */
+
+static inline bool vmm_user_handles_cpuid(uint32_t eax, uint32_t ecx)
+{
+       switch (eax) {
+       case 0x0b:
+               return true;
+       }
+       return false;
+}
index 83de9c0..b3e902c 100644 (file)
@@ -901,8 +901,8 @@ static bool handle_vmexit_cpuid(struct vm_trapframe *tf)
        const char kvm_sig[] = "KVMKVMKVM\0\0\0";
        const char akaros_sig[] = "AKAROSINSIDE";
 
-       if (tf->tf_rax == 0x0B)
-               return FALSE;   // Handle in userspace.
+       if (vmm_user_handles_cpuid(tf->tf_rax, tf->tf_rcx))
+               return false;
 
        cpuid(tf->tf_rax, tf->tf_rcx, &eax, &ebx, &ecx, &edx);
        switch (tf->tf_rax) {
index 172ee08..6150081 100644 (file)
@@ -83,32 +83,42 @@ static bool handle_cpuid(struct guest_thread *gth)
 {
        struct vm_trapframe *vm_tf = gth_to_vmtf(gth);
        struct virtual_machine *vm = gth_to_vm(gth);
-       uint32_t level = vm_tf->tf_rcx & 0x0F;
+       uint32_t eax = vm_tf->tf_rax;
+       uint32_t ecx = vm_tf->tf_rcx;
 
-       if (vm_tf->tf_rax != 0x0B)
-               return FALSE;
-
-       vm_tf->tf_rip += 2;
-       vm_tf->tf_rax = 0;
-       vm_tf->tf_rbx = 0;
-       vm_tf->tf_rcx = level;
-       vm_tf->tf_rdx = gth->gpc_id;
-       if (level == CPUID_0B_LEVEL_SMT) {
-               vm_tf->tf_rax = 0;
-               vm_tf->tf_rbx = 1;
-               vm_tf->tf_rcx |= ((level + 1) << 8);
+       if (!vmm_user_handles_cpuid(eax, ecx)) {
+               fprintf(stderr, "got an unexpected cpuid 0x%x:%x\n", eax, ecx);
+               return false;
        }
-       if (level == CPUID_0B_LEVEL_CORE) {
-               uint32_t shift = LOG2_UP(vm->nr_gpcs);
-
-               if (shift > 0x1F)
-                       shift = 0x1F;
-               vm_tf->tf_rax = shift;
-               vm_tf->tf_rbx = vm->nr_gpcs;
-               vm_tf->tf_rcx |= ((level + 1) << 8);
+
+       switch (eax) {
+       case 0x0b: {
+               uint32_t level = vm_tf->tf_rcx & 0x0F;
+
+               vm_tf->tf_rcx = level;
+               vm_tf->tf_rdx = gth->gpc_id;
+               if (level == CPUID_0B_LEVEL_SMT) {
+                       vm_tf->tf_rax = 0;
+                       vm_tf->tf_rbx = 1;
+                       vm_tf->tf_rcx |= ((level + 1) << 8);
+               }
+               if (level == CPUID_0B_LEVEL_CORE) {
+                       uint32_t shift = LOG2_UP(vm->nr_gpcs);
+
+                       if (shift > 0x1F)
+                               shift = 0x1F;
+                       vm_tf->tf_rax = shift;
+                       vm_tf->tf_rbx = vm->nr_gpcs;
+                       vm_tf->tf_rcx |= ((level + 1) << 8);
+               }
+       }        break;
+       default:
+               fprintf(stderr, "got an unhandled cpuid 0x%x:%x\n", eax, ecx);
+               return false;
        }
 
-       return TRUE;
+       vm_tf->tf_rip += 2;
+       return true;
 }
 
 static bool handle_ept_fault(struct guest_thread *gth)