Re: [PATCH v2] KVM: VMX: Fix crash due to uninitialized current_vmcs

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

 



Sean Christopherson <seanjc@xxxxxxxxxx> writes:

> On Mon, Jan 23, 2023, Sean Christopherson wrote:
>> On Mon, Jan 23, 2023, Alexandru Matei wrote:
>> > > .. or, alternatively, you can directly pass 
>> > > (struct hv_enlightened_vmcs *)vmx->vmcs01.vmcs as e.g. 'current_evmcs'
>> > > and avoid the conversion here.
>> > 
>> > OK, sounds good, I'll pass hv_enlightened_vmcs * directly.
>> 
>> Passing the eVMCS is silly, if we're going to bleed eVMCS details into vmx.c then
>> we should just commit and expose all details.  For this feature specifically, KVM
>> already handles the enabling in vmx.c / vmx_vcpu_create():
>> 
>> 	if (IS_ENABLED(CONFIG_HYPERV) && static_branch_unlikely(&enable_evmcs) &&
>> 	    (ms_hyperv.nested_features & HV_X64_NESTED_MSR_BITMAP)) {
>> 		struct hv_enlightened_vmcs *evmcs = (void *)vmx->vmcs01.vmcs;
>> 
>> 		evmcs->hv_enlightenments_control.msr_bitmap = 1;
>> 	}
>> 
>> And if we handle this fully in vmx_msr_bitmap_l01_changed(), then there's no need
>> for a comment explaining that the feature is only enabled for vmcs01.
>
> Oh, and the sanity check on a null pointer also goes away.
>
>> If we want to maintain better separate between VMX and Hyper-V code, then just make
>> the helper non-inline in hyperv.c, modifying MSR bitmaps will never be a hot path
>> for any sane guest.
>> 
>> I don't think I have a strong preference either way.  In a perfect world we'd keep
>> Hyper-V code separate, but practically speaking I think trying to move everything
>> into hyperv.c would result in far too many stubs and some weird function names.
>> 
>> Side topic, we should really have a wrapper for static_branch_unlikely(&enable_evmcs)
>> so that the static key can be defined iff CONFIG_HYPERV=y.  I'll send a patch.
>
> I.e.
>
> ---
>  arch/x86/kvm/vmx/hyperv.h | 11 -----------
>  arch/x86/kvm/vmx/vmx.c    |  9 +++++++--
>  2 files changed, 7 insertions(+), 13 deletions(-)
>
> diff --git a/arch/x86/kvm/vmx/hyperv.h b/arch/x86/kvm/vmx/hyperv.h
> index ab08a9b9ab7d..bac614e40078 100644
> --- a/arch/x86/kvm/vmx/hyperv.h
> +++ b/arch/x86/kvm/vmx/hyperv.h
> @@ -250,16 +250,6 @@ static inline u16 evmcs_read16(unsigned long field)
>  	return *(u16 *)((char *)current_evmcs + offset);
>  }
>  
> -static inline void evmcs_touch_msr_bitmap(void)
> -{
> -	if (unlikely(!current_evmcs))
> -		return;
> -
> -	if (current_evmcs->hv_enlightenments_control.msr_bitmap)
> -		current_evmcs->hv_clean_fields &=
> -			~HV_VMX_ENLIGHTENED_CLEAN_FIELD_MSR_BITMAP;
> -}
> -
>  static inline void evmcs_load(u64 phys_addr)
>  {
>  	struct hv_vp_assist_page *vp_ap =
> @@ -280,7 +270,6 @@ static inline u64 evmcs_read64(unsigned long field) { return 0; }
>  static inline u32 evmcs_read32(unsigned long field) { return 0; }
>  static inline u16 evmcs_read16(unsigned long field) { return 0; }
>  static inline void evmcs_load(u64 phys_addr) {}
> -static inline void evmcs_touch_msr_bitmap(void) {}
>  #endif /* IS_ENABLED(CONFIG_HYPERV) */
>  
>  #define EVMPTR_INVALID (-1ULL)
> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index c788aa382611..ed4051b54412 100644
> --- a/arch/x86/kvm/vmx/vmx.c
> +++ b/arch/x86/kvm/vmx/vmx.c
> @@ -3936,8 +3936,13 @@ static void vmx_msr_bitmap_l01_changed(struct vcpu_vmx *vmx)
>  	 * 'Enlightened MSR Bitmap' feature L0 needs to know that MSR
>  	 * bitmap has changed.
>  	 */
> -	if (static_branch_unlikely(&enable_evmcs))
> -		evmcs_touch_msr_bitmap();
> +	if (IS_ENABLED(CONFIG_HYPERV) && static_branch_unlikely(&enable_evmcs)) {
> +		struct hv_enlightened_vmcs *evmcs = (void *)vmx->vmcs01.vmcs;
> +
> +		if (evmcs->hv_enlightenments_control.msr_bitmap)
> +			evmcs->hv_clean_fields &=
> +				~HV_VMX_ENLIGHTENED_CLEAN_FIELD_MSR_BITMAP;
> +	}

With only one evmcs_touch_msr_bitmap() user in the tree, I think such
mixing of VMX and eVMCS is fine but honestly I like Alexandru's v3 more
as the "struct hv_enlightened_vmcs *" cast is the only thing which
"leaks" into VMX. Either way, no big deal)

>  
>  	vmx->nested.force_msr_bitmap_recalc = true;
>  }
>
> base-commit: 68bfbbf518a25856c2a3f07ea9d0c626f1b001fb

-- 
Vitaly




[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