Commit 70f932ec authored by Sean Christopherson's avatar Sean Christopherson Committed by Paolo Bonzini
Browse files

KVM: VMX: Add builder macros for shadowing controls



... to pave the way for shadowing all (five) major VMCS control fields
without massive amounts of error prone copy+paste+modify.

Signed-off-by: default avatarSean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent c075c3e4
Loading
Loading
Loading
Loading
+36 −64
Original line number Diff line number Diff line
@@ -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)
{