VMM: Add helpers for vmcs_read() and vmcs_write()
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 1 Feb 2016 15:40:17 +0000 (10:40 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 2 Feb 2016 22:43:52 +0000 (17:43 -0500)
VMCS read and write always transfer 64 bits (since we're in 64 bit mode)
regardless of the size of the field.

Additionally, I added a return value to vmcs_write(), so that callers can
check if a write failed.

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

index 83d27e9..9aa6265 100644 (file)
@@ -277,10 +277,7 @@ vmcs_get_current(void)
 __always_inline unsigned long
 vmcs_readl(unsigned long field)
 {
-       unsigned long value;
-
-       asm volatile (ASM_VMX_VMREAD_RDX_RAX:"=a"(value):"d"(field):"cc");
-       return value;
+       return vmcs_read(field);
 }
 
 __always_inline uint16_t
@@ -311,11 +308,7 @@ vmwrite_error(unsigned long field, unsigned long value)
 void
 vmcs_writel(unsigned long field, unsigned long value)
 {
-       uint8_t error;
-
-       asm volatile (ASM_VMX_VMWRITE_RAX_RDX "; setna %0":"=q"(error):"a"(value),
-                                 "d"(field):"cc");
-       if (error)
+       if (!vmcs_write(field, value))
                vmwrite_error(field, value);
 }
 
index 5dd62fd..a95de07 100644 (file)
@@ -264,6 +264,24 @@ static inline uint64_t vcpu_get_eptp(struct vmx_vcpu *vcpu)
        return vcpu->proc->env_pgdir.eptp;
 }
 
+static inline unsigned long vmcs_read(unsigned long field)
+{
+       unsigned long value;
+
+       asm volatile (ASM_VMX_VMREAD_RDX_RAX : "=a"(value) : "d"(field) : "cc");
+       return value;
+}
+
+/* Returns true if the op succeeded.  It can fail if the field is unsupported */
+static inline bool vmcs_write(unsigned long field, unsigned long value)
+{
+       uint8_t error;
+
+       asm volatile (ASM_VMX_VMWRITE_RAX_RDX "; setna %0"
+                     : "=q"(error) : "a"(value), "d"(field) : "cc");
+       return error ? FALSE : TRUE;
+}
+
 /*
  * VMX Execution Controls (vmxec)
  * Some bits can be set, others can not (i.e. they are reserved).