KVM: VMX: Add builder macros for shadowing controls
authorSean Christopherson <sean.j.christopherson@intel.com>
Tue, 7 May 2019 19:17:54 +0000 (12:17 -0700)
committerPaolo Bonzini <pbonzini@redhat.com>
Tue, 18 Jun 2019 09:47:40 +0000 (11:47 +0200)
... to pave the way for shadowing all (five) major VMCS control fields
without massive amounts of error prone copy+paste+modify.

Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/vmx/vmx.h

index 7f67f32..db4f928 100644 (file)
@@ -85,6 +85,11 @@ struct pt_desc {
        struct pt_ctx guest;
 };
 
+struct vmx_controls_shadow {
+       u32 vm_entry;
+       u32 vm_exit;
+};
+
 /*
  * The nested_vmx structure is part of vcpu_vmx, and holds information we need
  * for correct emulation of VMX (i.e., nested VMX) on this vcpu.
@@ -200,6 +205,9 @@ struct vcpu_vmx {
        u32                   exit_intr_info;
        u32                   idt_vectoring_info;
        ulong                 rflags;
+
+       struct vmx_controls_shadow      controls_shadow;
+
        struct shared_msr_entry *guest_msrs;
        int                   nmsrs;
        int                   save_nmsrs;
@@ -211,8 +219,6 @@ struct vcpu_vmx {
 
        u64                   spec_ctrl;
 
-       u32 vm_entry_controls_shadow;
-       u32 vm_exit_controls_shadow;
        u32 secondary_exec_control;
 
        /*
@@ -388,69 +394,35 @@ static inline u8 vmx_get_rvi(void)
        return vmcs_read16(GUEST_INTR_STATUS) & 0xff;
 }
 
-static inline void vm_entry_controls_reset_shadow(struct vcpu_vmx *vmx)
-{
-       vmx->vm_entry_controls_shadow = vmcs_read32(VM_ENTRY_CONTROLS);
-}
-
-static inline void vm_entry_controls_init(struct vcpu_vmx *vmx, u32 val)
-{
-       vmcs_write32(VM_ENTRY_CONTROLS, val);
-       vmx->vm_entry_controls_shadow = val;
-}
-
-static inline void vm_entry_controls_set(struct vcpu_vmx *vmx, u32 val)
-{
-       if (vmx->vm_entry_controls_shadow != val)
-               vm_entry_controls_init(vmx, val);
-}
-
-static inline u32 vm_entry_controls_get(struct vcpu_vmx *vmx)
-{
-       return vmx->vm_entry_controls_shadow;
-}
-
-static inline void vm_entry_controls_setbit(struct vcpu_vmx *vmx, u32 val)
-{
-       vm_entry_controls_set(vmx, vm_entry_controls_get(vmx) | val);
-}
-
-static inline void vm_entry_controls_clearbit(struct vcpu_vmx *vmx, u32 val)
-{
-       vm_entry_controls_set(vmx, vm_entry_controls_get(vmx) & ~val);
-}
-
-static inline void vm_exit_controls_reset_shadow(struct vcpu_vmx *vmx)
-{
-       vmx->vm_exit_controls_shadow = vmcs_read32(VM_EXIT_CONTROLS);
-}
-
-static inline void vm_exit_controls_init(struct vcpu_vmx *vmx, u32 val)
-{
-       vmcs_write32(VM_EXIT_CONTROLS, val);
-       vmx->vm_exit_controls_shadow = val;
-}
-
-static inline void vm_exit_controls_set(struct vcpu_vmx *vmx, u32 val)
-{
-       if (vmx->vm_exit_controls_shadow != val)
-               vm_exit_controls_init(vmx, val);
-}
-
-static inline u32 vm_exit_controls_get(struct vcpu_vmx *vmx)
-{
-       return vmx->vm_exit_controls_shadow;
-}
-
-static inline void vm_exit_controls_setbit(struct vcpu_vmx *vmx, u32 val)
-{
-       vm_exit_controls_set(vmx, vm_exit_controls_get(vmx) | val);
-}
-
-static inline void vm_exit_controls_clearbit(struct vcpu_vmx *vmx, u32 val)
-{
-       vm_exit_controls_set(vmx, vm_exit_controls_get(vmx) & ~val);
+#define BUILD_CONTROLS_SHADOW(lname, uname)                                \
+static inline void lname##_controls_reset_shadow(struct vcpu_vmx *vmx)     \
+{                                                                          \
+       vmx->controls_shadow.lname = vmcs_read32(uname);                    \
+}                                                                          \
+static inline void lname##_controls_init(struct vcpu_vmx *vmx, u32 val)            \
+{                                                                          \
+       vmcs_write32(uname, val);                                           \
+       vmx->controls_shadow.lname = val;                                   \
+}                                                                          \
+static inline void lname##_controls_set(struct vcpu_vmx *vmx, u32 val)     \
+{                                                                          \
+       if (vmx->controls_shadow.lname != val)                              \
+               lname##_controls_init(vmx, val);                            \
+}                                                                          \
+static inline u32 lname##_controls_get(struct vcpu_vmx *vmx)               \
+{                                                                          \
+       return vmx->controls_shadow.lname;                                  \
+}                                                                          \
+static inline void lname##_controls_setbit(struct vcpu_vmx *vmx, u32 val)   \
+{                                                                          \
+       lname##_controls_set(vmx, lname##_controls_get(vmx) | val);         \
+}                                                                          \
+static inline void lname##_controls_clearbit(struct vcpu_vmx *vmx, u32 val) \
+{                                                                          \
+       lname##_controls_set(vmx, lname##_controls_get(vmx) & ~val);        \
 }
+BUILD_CONTROLS_SHADOW(vm_entry, VM_ENTRY_CONTROLS)
+BUILD_CONTROLS_SHADOW(vm_exit, VM_EXIT_CONTROLS)
 
 static inline void vmx_segment_cache_clear(struct vcpu_vmx *vmx)
 {