2022-07-08 15:06:35

by Vitaly Kuznetsov

[permalink] [raw]
Subject: [PATCH v3 15/25] KVM: VMX: Extend VMX controls macro shenanigans

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 <[email protected]>
Signed-off-by: Vitaly Kuznetsov <[email protected]>
---
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;
#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;
@@ -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);
}

- 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;

- 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;

@@ -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)
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)
--
2.35.3


2022-07-12 11:59:48

by Maxim Levitsky

[permalink] [raw]
Subject: Re: [PATCH v3 15/25] KVM: VMX: Extend VMX controls macro shenanigans

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 <[email protected]>
> Signed-off-by: Vitaly Kuznetsov <[email protected]>
> ---
>  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 <[email protected]>

Best regards,
Maxim Levitsky