1
0
Fork 0

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: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
alistair/sunxi64-5.4-dsi
Sean Christopherson 2019-05-07 12:17:54 -07:00 committed by Paolo Bonzini
parent c075c3e49d
commit 70f932ecdf
1 changed files with 36 additions and 64 deletions

View 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)
{