VMM: Add a helper to emulate MSRs [1/4]
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 1 Feb 2016 16:11:53 +0000 (11:11 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 2 Feb 2016 22:43:52 +0000 (17:43 -0500)
The existing msrio() is too ingrained in the KVM/Dune style of operations.
It'll work a little easier with pointers to the registers and not having a
ret value that is a VMX header value.

The existing implementation of MSR emulation is in vmx.c, though for the
most part it is VMX-independent.  The one bit that is from VMX is using the
opcodes from VMX exits to specify whether we're reading or writing.  That
will change shortly.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/arch/x86/vmm/intel/vmx.c
kern/arch/x86/vmm/vmm.h

index b0a7c2c..7cb576c 100644 (file)
@@ -1397,21 +1397,24 @@ bool emsr_fake_apicbase(struct emmsr *msr, uint64_t *rcx, uint64_t *rdx,
        return TRUE;
 }
 
+bool vmm_emulate_msr(uint64_t *rcx, uint64_t *rdx, uint64_t *rax, int op)
+{
+       for (int i = 0; i < ARRAY_SIZE(emmsrs); i++) {
+               if (emmsrs[i].reg != *rcx)
+                       continue;
+               return emmsrs[i].f(&emmsrs[i], rcx, rdx, rax, op);
+       }
+       return FALSE;
+}
 
 static int
 msrio(struct vmx_vcpu *vcpu, uint32_t opcode, uint32_t qual) {
        int i;
-       for (i = 0; i < ARRAY_SIZE(emmsrs); i++) {
-               if (emmsrs[i].reg != vcpu->regs.tf_rcx)
-                       continue;
-               if (emmsrs[i].f(&emmsrs[i], &vcpu->regs.tf_rcx, &vcpu->regs.tf_rdx,
-                               &vcpu->regs.tf_rax, opcode))
-                       return 0;
-               else
-                       return SHUTDOWN_UNHANDLED_EXIT_REASON;
-       }
-       printk("msrio for 0x%lx failed\n", vcpu->regs.tf_rcx);
-       return SHUTDOWN_UNHANDLED_EXIT_REASON;
+
+       if (!vmm_emulate_msr(&vcpu->regs.tf_rcx, &vcpu->regs.tf_rdx,
+                            &vcpu->regs.tf_rax, opcode))
+               return SHUTDOWN_UNHANDLED_EXIT_REASON;
+       return 0;
 }
 
 /* Notes on autoloading.  We can't autoload FS_BASE or GS_BASE, according to the
index ec1a1bc..49c6602 100644 (file)
@@ -64,3 +64,5 @@ void ept_flush(uint64_t eptp);
 struct vmx_vcpu *lookup_guest_pcore(struct proc *p, int guest_pcoreid);
 struct vmx_vcpu *load_guest_pcore(struct proc *p, int guest_pcoreid);
 void unload_guest_pcore(struct proc *p, int guest_pcoreid);
+
+bool vmm_emulate_msr(uint64_t *rcx, uint64_t *rdx, uint64_t *rax, int op);