On Fri, 2022-07-08 at 16:42 +0200, Vitaly Kuznetsov wrote: > When VMX controls macros are used to set or clear a control bit, make > sure that this bit was checked in setup_vmcs_config() and thus is properly > reflected in vmcs_config. > > No functional change intended. > > Suggested-by: Sean Christopherson <seanjc@xxxxxxxxxx> > Signed-off-by: Vitaly Kuznetsov <vkuznets@xxxxxxxxxx> > --- > arch/x86/kvm/vmx/vmx.c | 99 +++++++------------------------------ > arch/x86/kvm/vmx/vmx.h | 109 +++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 127 insertions(+), 81 deletions(-) > > diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c > index 566be73c6509..93ca9ff8e641 100644 > --- a/arch/x86/kvm/vmx/vmx.c > +++ b/arch/x86/kvm/vmx/vmx.c > @@ -2448,7 +2448,6 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf, > struct vmx_capability *vmx_cap) > { > u32 vmx_msr_low, vmx_msr_high; > - u32 min, opt, min2, opt2; > u32 _pin_based_exec_control = 0; > u32 _cpu_based_exec_control = 0; > u32 _cpu_based_2nd_exec_control = 0; > @@ -2474,28 +2473,10 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf, > }; > > memset(vmcs_conf, 0, sizeof(*vmcs_conf)); > - min = CPU_BASED_HLT_EXITING | > -#ifdef CONFIG_X86_64 > - CPU_BASED_CR8_LOAD_EXITING | > - CPU_BASED_CR8_STORE_EXITING | > -#endif > - CPU_BASED_CR3_LOAD_EXITING | > - CPU_BASED_CR3_STORE_EXITING | > - CPU_BASED_UNCOND_IO_EXITING | > - CPU_BASED_MOV_DR_EXITING | > - CPU_BASED_USE_TSC_OFFSETTING | > - CPU_BASED_MWAIT_EXITING | > - CPU_BASED_MONITOR_EXITING | > - CPU_BASED_INVLPG_EXITING | > - CPU_BASED_RDPMC_EXITING | > - CPU_BASED_INTR_WINDOW_EXITING; > - > - opt = CPU_BASED_TPR_SHADOW | > - CPU_BASED_USE_MSR_BITMAPS | > - CPU_BASED_NMI_WINDOW_EXITING | > - CPU_BASED_ACTIVATE_SECONDARY_CONTROLS | > - CPU_BASED_ACTIVATE_TERTIARY_CONTROLS; > - if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PROCBASED_CTLS, > + > + if (adjust_vmx_controls(KVM_REQ_VMX_CPU_BASED_VM_EXEC_CONTROL, > + KVM_OPT_VMX_CPU_BASED_VM_EXEC_CONTROL, > + MSR_IA32_VMX_PROCBASED_CTLS, > &_cpu_based_exec_control) < 0) > return -EIO; OK > #ifdef CONFIG_X86_64 > @@ -2504,34 +2485,8 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf, > ~CPU_BASED_CR8_STORE_EXITING; > #endif > if (_cpu_based_exec_control & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS) { > - min2 = 0; > - opt2 = SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | > - SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | > - SECONDARY_EXEC_WBINVD_EXITING | > - SECONDARY_EXEC_ENABLE_VPID | > - SECONDARY_EXEC_ENABLE_EPT | > - SECONDARY_EXEC_UNRESTRICTED_GUEST | > - SECONDARY_EXEC_PAUSE_LOOP_EXITING | > - SECONDARY_EXEC_DESC | > - SECONDARY_EXEC_ENABLE_RDTSCP | > - SECONDARY_EXEC_ENABLE_INVPCID | > - SECONDARY_EXEC_APIC_REGISTER_VIRT | > - SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | > - SECONDARY_EXEC_SHADOW_VMCS | > - SECONDARY_EXEC_XSAVES | > - SECONDARY_EXEC_RDSEED_EXITING | > - SECONDARY_EXEC_RDRAND_EXITING | > - SECONDARY_EXEC_ENABLE_PML | > - SECONDARY_EXEC_TSC_SCALING | > - SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE | > - SECONDARY_EXEC_PT_USE_GPA | > - SECONDARY_EXEC_PT_CONCEAL_VMX | > - SECONDARY_EXEC_ENABLE_VMFUNC | > - SECONDARY_EXEC_BUS_LOCK_DETECTION | > - SECONDARY_EXEC_NOTIFY_VM_EXITING | > - SECONDARY_EXEC_ENCLS_EXITING; > - > - if (adjust_vmx_controls(min2, opt2, > + if (adjust_vmx_controls(KVM_REQ_VMX_SECONDARY_VM_EXEC_CONTROL, > + KVM_OPT_VMX_SECONDARY_VM_EXEC_CONTROL, > MSR_IA32_VMX_PROCBASED_CTLS2, > &_cpu_based_2nd_exec_control) < 0) > return -EIO; OK > @@ -2581,30 +2536,20 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf, > _cpu_based_2nd_exec_control &= ~SECONDARY_EXEC_ENCLS_EXITING; > > if (_cpu_based_exec_control & CPU_BASED_ACTIVATE_TERTIARY_CONTROLS) { > - u64 opt3 = TERTIARY_EXEC_IPI_VIRT; > - > - _cpu_based_3rd_exec_control = adjust_vmx_controls64(opt3, > - MSR_IA32_VMX_PROCBASED_CTLS3); > + _cpu_based_3rd_exec_control = > + adjust_vmx_controls64(KVM_OPT_VMX_TERTIARY_VM_EXEC_CONTROL, > + MSR_IA32_VMX_PROCBASED_CTLS3); > } OK > > - min = VM_EXIT_SAVE_DEBUG_CONTROLS | VM_EXIT_ACK_INTR_ON_EXIT; > -#ifdef CONFIG_X86_64 > - min |= VM_EXIT_HOST_ADDR_SPACE_SIZE; > -#endif > - opt = VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | > - VM_EXIT_LOAD_IA32_PAT | > - VM_EXIT_LOAD_IA32_EFER | > - VM_EXIT_CLEAR_BNDCFGS | > - VM_EXIT_PT_CONCEAL_PIP | > - VM_EXIT_CLEAR_IA32_RTIT_CTL; > - if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_EXIT_CTLS, > + if (adjust_vmx_controls(KVM_REQ_VMX_VM_EXIT_CONTROLS, > + KVM_OPT_VMX_VM_EXIT_CONTROLS, > + MSR_IA32_VMX_EXIT_CTLS, > &_vmexit_control) < 0) > return -EIO; OK. > > - min = PIN_BASED_EXT_INTR_MASK | PIN_BASED_NMI_EXITING; > - opt = PIN_BASED_VIRTUAL_NMIS | PIN_BASED_POSTED_INTR | > - PIN_BASED_VMX_PREEMPTION_TIMER; > - if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PINBASED_CTLS, > + if (adjust_vmx_controls(KVM_REQ_VMX_PIN_BASED_VM_EXEC_CONTROL, > + KVM_OPT_VMX_PIN_BASED_VM_EXEC_CONTROL, > + MSR_IA32_VMX_PINBASED_CTLS, > &_pin_based_exec_control) < 0) > return -EIO; OK > > @@ -2614,17 +2559,9 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf, > SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY)) > _pin_based_exec_control &= ~PIN_BASED_POSTED_INTR; > > - min = VM_ENTRY_LOAD_DEBUG_CONTROLS; > -#ifdef CONFIG_X86_64 > - min |= VM_ENTRY_IA32E_MODE; > -#endif > - opt = VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | > - VM_ENTRY_LOAD_IA32_PAT | > - VM_ENTRY_LOAD_IA32_EFER | > - VM_ENTRY_LOAD_BNDCFGS | > - VM_ENTRY_PT_CONCEAL_PIP | > - VM_ENTRY_LOAD_IA32_RTIT_CTL; > - if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_ENTRY_CTLS, > + if (adjust_vmx_controls(KVM_REQ_VMX_VM_ENTRY_CONTROLS, > + KVM_OPT_VMX_VM_ENTRY_CONTROLS, > + MSR_IA32_VMX_ENTRY_CTLS, > &_vmentry_control) < 0) OK. > return -EIO; > > diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h > index 286c88e285ea..89eaab3495a6 100644 > --- a/arch/x86/kvm/vmx/vmx.h > +++ b/arch/x86/kvm/vmx/vmx.h > @@ -467,6 +467,113 @@ static inline u8 vmx_get_rvi(void) > return vmcs_read16(GUEST_INTR_STATUS) & 0xff; > } > > +#define __KVM_REQ_VMX_VM_ENTRY_CONTROLS \ > + (VM_ENTRY_LOAD_DEBUG_CONTROLS) > +#ifdef CONFIG_X86_64 > + #define KVM_REQ_VMX_VM_ENTRY_CONTROLS \ > + (__KVM_REQ_VMX_VM_ENTRY_CONTROLS | \ > + VM_ENTRY_IA32E_MODE) > +#else > + #define KVM_REQ_VMX_VM_ENTRY_CONTROLS \ > + __KVM_REQ_VMX_VM_ENTRY_CONTROLS > +#endif > +#define KVM_OPT_VMX_VM_ENTRY_CONTROLS \ > + (VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL | \ > + VM_ENTRY_LOAD_IA32_PAT | \ > + VM_ENTRY_LOAD_IA32_EFER | \ > + VM_ENTRY_LOAD_BNDCFGS | \ > + VM_ENTRY_PT_CONCEAL_PIP | \ > + VM_ENTRY_LOAD_IA32_RTIT_CTL) > + > +#define __KVM_REQ_VMX_VM_EXIT_CONTROLS \ > + (VM_EXIT_SAVE_DEBUG_CONTROLS | \ > + VM_EXIT_ACK_INTR_ON_EXIT) > +#ifdef CONFIG_X86_64 > + #define KVM_REQ_VMX_VM_EXIT_CONTROLS \ > + (__KVM_REQ_VMX_VM_EXIT_CONTROLS | \ > + VM_EXIT_HOST_ADDR_SPACE_SIZE) > +#else > + #define KVM_REQ_VMX_VM_EXIT_CONTROLS \ > + __KVM_REQ_VMX_VM_EXIT_CONTROLS > +#endif > +#define KVM_OPT_VMX_VM_EXIT_CONTROLS \ > + (VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | \ > + VM_EXIT_LOAD_IA32_PAT | \ > + VM_EXIT_LOAD_IA32_EFER | \ > + VM_EXIT_CLEAR_BNDCFGS | \ > + VM_EXIT_PT_CONCEAL_PIP | \ > + VM_EXIT_CLEAR_IA32_RTIT_CTL) > + > +#define KVM_REQ_VMX_PIN_BASED_VM_EXEC_CONTROL \ > + (PIN_BASED_EXT_INTR_MASK | \ > + PIN_BASED_NMI_EXITING) > +#define KVM_OPT_VMX_PIN_BASED_VM_EXEC_CONTROL \ > + (PIN_BASED_VIRTUAL_NMIS | \ > + PIN_BASED_POSTED_INTR | \ > + PIN_BASED_VMX_PREEMPTION_TIMER) > + > +#define __KVM_REQ_VMX_CPU_BASED_VM_EXEC_CONTROL \ > + (CPU_BASED_HLT_EXITING | \ > + CPU_BASED_CR3_LOAD_EXITING | \ > + CPU_BASED_CR3_STORE_EXITING | \ > + CPU_BASED_UNCOND_IO_EXITING | \ > + CPU_BASED_MOV_DR_EXITING | \ > + CPU_BASED_USE_TSC_OFFSETTING | \ > + CPU_BASED_MWAIT_EXITING | \ > + CPU_BASED_MONITOR_EXITING | \ > + CPU_BASED_INVLPG_EXITING | \ > + CPU_BASED_RDPMC_EXITING | \ > + CPU_BASED_INTR_WINDOW_EXITING) > + > +#ifdef CONFIG_X86_64 > + #define KVM_REQ_VMX_CPU_BASED_VM_EXEC_CONTROL \ > + (__KVM_REQ_VMX_CPU_BASED_VM_EXEC_CONTROL | \ > + CPU_BASED_CR8_LOAD_EXITING | \ > + CPU_BASED_CR8_STORE_EXITING) > +#else > + #define KVM_REQ_VMX_CPU_BASED_VM_EXEC_CONTROL \ > + __KVM_REQ_VMX_CPU_BASED_VM_EXEC_CONTROL > +#endif > + > +#define KVM_OPT_VMX_CPU_BASED_VM_EXEC_CONTROL \ > + (CPU_BASED_TPR_SHADOW | \ > + CPU_BASED_USE_MSR_BITMAPS | \ > + CPU_BASED_NMI_WINDOW_EXITING | \ > + CPU_BASED_ACTIVATE_SECONDARY_CONTROLS | \ > + CPU_BASED_ACTIVATE_TERTIARY_CONTROLS) > + > +#define KVM_REQ_VMX_SECONDARY_VM_EXEC_CONTROL 0 > +#define KVM_OPT_VMX_SECONDARY_VM_EXEC_CONTROL \ > + (SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | \ > + SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | \ > + SECONDARY_EXEC_WBINVD_EXITING | \ > + SECONDARY_EXEC_ENABLE_VPID | \ > + SECONDARY_EXEC_ENABLE_EPT | \ > + SECONDARY_EXEC_UNRESTRICTED_GUEST | \ > + SECONDARY_EXEC_PAUSE_LOOP_EXITING | \ > + SECONDARY_EXEC_DESC | \ > + SECONDARY_EXEC_ENABLE_RDTSCP | \ > + SECONDARY_EXEC_ENABLE_INVPCID | \ > + SECONDARY_EXEC_APIC_REGISTER_VIRT | \ > + SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | \ > + SECONDARY_EXEC_SHADOW_VMCS | \ > + SECONDARY_EXEC_XSAVES | \ > + SECONDARY_EXEC_RDSEED_EXITING | \ > + SECONDARY_EXEC_RDRAND_EXITING | \ > + SECONDARY_EXEC_ENABLE_PML | \ > + SECONDARY_EXEC_TSC_SCALING | \ > + SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE | \ > + SECONDARY_EXEC_PT_USE_GPA | \ > + SECONDARY_EXEC_PT_CONCEAL_VMX | \ > + SECONDARY_EXEC_ENABLE_VMFUNC | \ > + SECONDARY_EXEC_BUS_LOCK_DETECTION | \ > + SECONDARY_EXEC_NOTIFY_VM_EXITING | \ > + SECONDARY_EXEC_ENCLS_EXITING) > + > +#define KVM_REQ_VMX_TERTIARY_VM_EXEC_CONTROL 0 > +#define KVM_OPT_VMX_TERTIARY_VM_EXEC_CONTROL \ > + (TERTIARY_EXEC_IPI_VIRT) > + > #define BUILD_CONTROLS_SHADOW(lname, uname, bits) \ > static inline void lname##_controls_set(struct vcpu_vmx *vmx, u##bits val) \ > { \ > @@ -485,10 +592,12 @@ static inline u##bits lname##_controls_get(struct vcpu_vmx *vmx) \ > } \ > static inline void lname##_controls_setbit(struct vcpu_vmx *vmx, u##bits val) \ > { \ > + BUILD_BUG_ON(!(val & (KVM_REQ_VMX_##uname | KVM_OPT_VMX_##uname))); \ > lname##_controls_set(vmx, lname##_controls_get(vmx) | val); \ > } \ > static inline void lname##_controls_clearbit(struct vcpu_vmx *vmx, u##bits val) \ > { \ > + BUILD_BUG_ON(!(val & (KVM_REQ_VMX_##uname | KVM_OPT_VMX_##uname))); \ > lname##_controls_set(vmx, lname##_controls_get(vmx) & ~val); \ > } > BUILD_CONTROLS_SHADOW(vm_entry, VM_ENTRY_CONTROLS, 32) I cross checked that all bits were copied correctly. This patch is a very nice idea! Reviewed-by: Maxim Levitsky <mlevitsk@xxxxxxxxxx> Best regards, Maxim Levitsky