RE: [PATCH 04/14] KVM: VMX: Extend VMX controls macro shenanigans

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




> -----Original Message-----
> From: Vitaly Kuznetsov <vkuznets@xxxxxxxxxx>
> Sent: Monday, June 27, 2022 9:05 AM
> To: kvm@xxxxxxxxxxxxxxx; Paolo Bonzini <pbonzini@xxxxxxxxxx>;
> Christopherson,, Sean <seanjc@xxxxxxxxxx>
> Cc: Anirudh Rayabharam <anrayabh@xxxxxxxxxxxxxxxxxxx>; Wanpeng Li
> <wanpengli@xxxxxxxxxxx>; Jim Mattson <jmattson@xxxxxxxxxx>; Maxim
> Levitsky <mlevitsk@xxxxxxxxxx>; linux-hyperv@xxxxxxxxxxxxxxx; linux-
> kernel@xxxxxxxxxxxxxxx
> Subject: [PATCH 04/14] 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 <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
> 5300f2ad6a25..7ef4bc69e2c6 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 |
> -	      CPU_BASED_NMI_WINDOW_EXITING;
> -
> -	opt = CPU_BASED_TPR_SHADOW |
> -	      CPU_BASED_USE_MSR_BITMAPS |
> -	      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_CON
> TROL,
> +			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..540febecac92 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 |				\
> +	CPU_BASED_NMI_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_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);
> 	\
>  }

With this, will it be safer if we present L1 CTRL MSRs with the bits KVM really uses? Do I miss something?

>  BUILD_CONTROLS_SHADOW(vm_entry, VM_ENTRY_CONTROLS, 32)
> --
> 2.35.3





[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux