diff options
author | Sean Christopherson <sean.j.christopherson@intel.com> | 2019-05-07 15:17:54 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2019-06-18 05:47:40 -0400 |
commit | 70f932ecdfe6b593ef6784d55d2c096aafac1510 (patch) | |
tree | 084cffb931dc00b46cf40901b48c4c0750521fa2 | |
parent | c075c3e49d7ae3599106f1af53352268030469db (diff) |
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>
-rw-r--r-- | arch/x86/kvm/vmx/vmx.h | 100 |
1 files changed, 36 insertions, 64 deletions
diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index 7f67f327204a..db4f9289d5da 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h | |||
@@ -85,6 +85,11 @@ struct pt_desc { | |||
85 | struct pt_ctx guest; | 85 | struct pt_ctx guest; |
86 | }; | 86 | }; |
87 | 87 | ||
88 | struct vmx_controls_shadow { | ||
89 | u32 vm_entry; | ||
90 | u32 vm_exit; | ||
91 | }; | ||
92 | |||
88 | /* | 93 | /* |
89 | * The nested_vmx structure is part of vcpu_vmx, and holds information we need | 94 | * The nested_vmx structure is part of vcpu_vmx, and holds information we need |
90 | * for correct emulation of VMX (i.e., nested VMX) on this vcpu. | 95 | * for correct emulation of VMX (i.e., nested VMX) on this vcpu. |
@@ -200,6 +205,9 @@ struct vcpu_vmx { | |||
200 | u32 exit_intr_info; | 205 | u32 exit_intr_info; |
201 | u32 idt_vectoring_info; | 206 | u32 idt_vectoring_info; |
202 | ulong rflags; | 207 | ulong rflags; |
208 | |||
209 | struct vmx_controls_shadow controls_shadow; | ||
210 | |||
203 | struct shared_msr_entry *guest_msrs; | 211 | struct shared_msr_entry *guest_msrs; |
204 | int nmsrs; | 212 | int nmsrs; |
205 | int save_nmsrs; | 213 | int save_nmsrs; |
@@ -211,8 +219,6 @@ struct vcpu_vmx { | |||
211 | 219 | ||
212 | u64 spec_ctrl; | 220 | u64 spec_ctrl; |
213 | 221 | ||
214 | u32 vm_entry_controls_shadow; | ||
215 | u32 vm_exit_controls_shadow; | ||
216 | u32 secondary_exec_control; | 222 | u32 secondary_exec_control; |
217 | 223 | ||
218 | /* | 224 | /* |
@@ -388,69 +394,35 @@ static inline u8 vmx_get_rvi(void) | |||
388 | return vmcs_read16(GUEST_INTR_STATUS) & 0xff; | 394 | return vmcs_read16(GUEST_INTR_STATUS) & 0xff; |
389 | } | 395 | } |
390 | 396 | ||
391 | static inline void vm_entry_controls_reset_shadow(struct vcpu_vmx *vmx) | 397 | #define BUILD_CONTROLS_SHADOW(lname, uname) \ |
392 | { | 398 | static inline void lname##_controls_reset_shadow(struct vcpu_vmx *vmx) \ |
393 | vmx->vm_entry_controls_shadow = vmcs_read32(VM_ENTRY_CONTROLS); | 399 | { \ |
394 | } | 400 | vmx->controls_shadow.lname = vmcs_read32(uname); \ |
395 | 401 | } \ | |
396 | static inline void vm_entry_controls_init(struct vcpu_vmx *vmx, u32 val) | 402 | static inline void lname##_controls_init(struct vcpu_vmx *vmx, u32 val) \ |
397 | { | 403 | { \ |
398 | vmcs_write32(VM_ENTRY_CONTROLS, val); | 404 | vmcs_write32(uname, val); \ |
399 | vmx->vm_entry_controls_shadow = val; | 405 | vmx->controls_shadow.lname = val; \ |
400 | } | 406 | } \ |
401 | 407 | static inline void lname##_controls_set(struct vcpu_vmx *vmx, u32 val) \ | |
402 | static inline void vm_entry_controls_set(struct vcpu_vmx *vmx, u32 val) | 408 | { \ |
403 | { | 409 | if (vmx->controls_shadow.lname != val) \ |
404 | if (vmx->vm_entry_controls_shadow != val) | 410 | lname##_controls_init(vmx, val); \ |
405 | vm_entry_controls_init(vmx, val); | 411 | } \ |
406 | } | 412 | static inline u32 lname##_controls_get(struct vcpu_vmx *vmx) \ |
407 | 413 | { \ | |
408 | static inline u32 vm_entry_controls_get(struct vcpu_vmx *vmx) | 414 | return vmx->controls_shadow.lname; \ |
409 | { | 415 | } \ |
410 | return vmx->vm_entry_controls_shadow; | 416 | static inline void lname##_controls_setbit(struct vcpu_vmx *vmx, u32 val) \ |
411 | } | 417 | { \ |
412 | 418 | lname##_controls_set(vmx, lname##_controls_get(vmx) | val); \ | |
413 | static inline void vm_entry_controls_setbit(struct vcpu_vmx *vmx, u32 val) | 419 | } \ |
414 | { | 420 | static inline void lname##_controls_clearbit(struct vcpu_vmx *vmx, u32 val) \ |
415 | vm_entry_controls_set(vmx, vm_entry_controls_get(vmx) | val); | 421 | { \ |
416 | } | 422 | lname##_controls_set(vmx, lname##_controls_get(vmx) & ~val); \ |
417 | |||
418 | static inline void vm_entry_controls_clearbit(struct vcpu_vmx *vmx, u32 val) | ||
419 | { | ||
420 | vm_entry_controls_set(vmx, vm_entry_controls_get(vmx) & ~val); | ||
421 | } | ||
422 | |||
423 | static inline void vm_exit_controls_reset_shadow(struct vcpu_vmx *vmx) | ||
424 | { | ||
425 | vmx->vm_exit_controls_shadow = vmcs_read32(VM_EXIT_CONTROLS); | ||
426 | } | ||
427 | |||
428 | static inline void vm_exit_controls_init(struct vcpu_vmx *vmx, u32 val) | ||
429 | { | ||
430 | vmcs_write32(VM_EXIT_CONTROLS, val); | ||
431 | vmx->vm_exit_controls_shadow = val; | ||
432 | } | ||
433 | |||
434 | static inline void vm_exit_controls_set(struct vcpu_vmx *vmx, u32 val) | ||
435 | { | ||
436 | if (vmx->vm_exit_controls_shadow != val) | ||
437 | vm_exit_controls_init(vmx, val); | ||
438 | } | ||
439 | |||
440 | static inline u32 vm_exit_controls_get(struct vcpu_vmx *vmx) | ||
441 | { | ||
442 | return vmx->vm_exit_controls_shadow; | ||
443 | } | ||
444 | |||
445 | static inline void vm_exit_controls_setbit(struct vcpu_vmx *vmx, u32 val) | ||
446 | { | ||
447 | vm_exit_controls_set(vmx, vm_exit_controls_get(vmx) | val); | ||
448 | } | ||
449 | |||
450 | static inline void vm_exit_controls_clearbit(struct vcpu_vmx *vmx, u32 val) | ||
451 | { | ||
452 | vm_exit_controls_set(vmx, vm_exit_controls_get(vmx) & ~val); | ||
453 | } | 423 | } |
424 | BUILD_CONTROLS_SHADOW(vm_entry, VM_ENTRY_CONTROLS) | ||
425 | BUILD_CONTROLS_SHADOW(vm_exit, VM_EXIT_CONTROLS) | ||
454 | 426 | ||
455 | static inline void vmx_segment_cache_clear(struct vcpu_vmx *vmx) | 427 | static inline void vmx_segment_cache_clear(struct vcpu_vmx *vmx) |
456 | { | 428 | { |