All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vitaly Kuznetsov <vkuznets@redhat.com>
To: Maxim Levitsky <mlevitsk@redhat.com>,
	kvm@vger.kernel.org, Paolo Bonzini <pbonzini@redhat.com>,
	Sean Christopherson <seanjc@google.com>
Cc: linux-kernel@vger.kernel.org
Subject: Re: [PATCH RFC 08/11] KVM: nVMX: hyper-v: Introduce nested_vmx_evmptr() accessor
Date: Mon, 16 Oct 2023 15:49:32 +0200	[thread overview]
Message-ID: <87edhu8yoj.fsf@redhat.com> (raw)
In-Reply-To: <406f20dc55db24dffda2e01a1ccf7a7135c61604.camel@redhat.com>

Maxim Levitsky <mlevitsk@redhat.com> writes:

> У вт, 2023-10-10 у 18:02 +0200, Vitaly Kuznetsov пише:
>> 'vmx->nested.hv_evmcs_vmptr' accesses are all over the place so hiding
>> 'hv_evmcs_vmptr' under 'ifdef CONFIG_KVM_HYPERV' would take a lot of
>> ifdefs. Introduce 'nested_vmx_evmptr()' accessor instead.
>
>
> It might also make sense to have 'nested_evmptr_valid(vmx)'
> so that we could use it instead of 'evmptr_is_valid(nested_vmx_evmptr(vmx))'?
>

Makes sense, thanks!

>
>> 
>> No functional change intended.
>> 
>> Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
>> ---
>>  arch/x86/kvm/vmx/hyperv.h |  5 +++++
>>  arch/x86/kvm/vmx/nested.c | 44 +++++++++++++++++++--------------------
>>  arch/x86/kvm/vmx/nested.h |  3 ++-
>>  3 files changed, 29 insertions(+), 23 deletions(-)
>> 
>> diff --git a/arch/x86/kvm/vmx/hyperv.h b/arch/x86/kvm/vmx/hyperv.h
>> index 933ef6cad5e6..6ca5c8c5be9c 100644
>> --- a/arch/x86/kvm/vmx/hyperv.h
>> +++ b/arch/x86/kvm/vmx/hyperv.h
>> @@ -4,6 +4,7 @@
>>  
>>  #include <linux/kvm_host.h>
>>  #include "vmcs12.h"
>> +#include "vmx.h"
>>  
>>  #define EVMPTR_INVALID (-1ULL)
>>  #define EVMPTR_MAP_PENDING (-2ULL)
>> @@ -20,7 +21,10 @@ enum nested_evmptrld_status {
>>  	EVMPTRLD_ERROR,
>>  };
>>  
>> +struct vcpu_vmx;
>> +
>>  #ifdef CONFIG_KVM_HYPERV
>> +static inline gpa_t nested_vmx_evmptr(struct vcpu_vmx *vmx) { return vmx->nested.hv_evmcs_vmptr; }
>>  u64 nested_get_evmptr(struct kvm_vcpu *vcpu);
>>  uint16_t nested_get_evmcs_version(struct kvm_vcpu *vcpu);
>>  int nested_enable_evmcs(struct kvm_vcpu *vcpu,
>> @@ -30,6 +34,7 @@ int nested_evmcs_check_controls(struct vmcs12 *vmcs12);
>>  bool nested_evmcs_l2_tlb_flush_enabled(struct kvm_vcpu *vcpu);
>>  void vmx_hv_inject_synthetic_vmexit_post_tlb_flush(struct kvm_vcpu *vcpu);
>>  #else
>> +static inline gpa_t nested_vmx_evmptr(struct vcpu_vmx *vmx) { return EVMPTR_INVALID; };
>>  static inline u64 nested_get_evmptr(struct kvm_vcpu *vcpu) { return EVMPTR_INVALID; }
>>  static inline void nested_evmcs_filter_control_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) {}
>>  static inline bool nested_evmcs_l2_tlb_flush_enabled(struct kvm_vcpu *vcpu) { return false; }
>> diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
>> index ca7e06759aa3..e6476f8e2ccd 100644
>> --- a/arch/x86/kvm/vmx/nested.c
>> +++ b/arch/x86/kvm/vmx/nested.c
>> @@ -179,7 +179,7 @@ static int nested_vmx_failValid(struct kvm_vcpu *vcpu,
>>  	 * VM_INSTRUCTION_ERROR is not shadowed. Enlightened VMCS 'shadows' all
>>  	 * fields and thus must be synced.
>>  	 */
>> -	if (to_vmx(vcpu)->nested.hv_evmcs_vmptr != EVMPTR_INVALID)
>> +	if (nested_vmx_evmptr(to_vmx(vcpu)) != EVMPTR_INVALID)
>>  		to_vmx(vcpu)->nested.need_vmcs12_to_shadow_sync = true;
>>  
>>  	return kvm_skip_emulated_instruction(vcpu);
>> @@ -194,7 +194,7 @@ static int nested_vmx_fail(struct kvm_vcpu *vcpu, u32 vm_instruction_error)
>>  	 * can't be done if there isn't a current VMCS.
>>  	 */
>>  	if (vmx->nested.current_vmptr == INVALID_GPA &&
>> -	    !evmptr_is_valid(vmx->nested.hv_evmcs_vmptr))
>> +	    !evmptr_is_valid(nested_vmx_evmptr(vmx)))
>>  		return nested_vmx_failInvalid(vcpu);
>>  
>>  	return nested_vmx_failValid(vcpu, vm_instruction_error);
>> @@ -230,7 +230,7 @@ static inline void nested_release_evmcs(struct kvm_vcpu *vcpu)
>>  	struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
>>  	struct vcpu_vmx *vmx = to_vmx(vcpu);
>>  
>> -	if (evmptr_is_valid(vmx->nested.hv_evmcs_vmptr)) {
>> +	if (evmptr_is_valid(nested_vmx_evmptr(vmx))) {
>>  		kvm_vcpu_unmap(vcpu, &vmx->nested.hv_evmcs_map, true);
>>  		vmx->nested.hv_evmcs = NULL;
>>  	}
>> @@ -2019,7 +2019,7 @@ static enum nested_evmptrld_status nested_vmx_handle_enlightened_vmptrld(
>>  		return EVMPTRLD_DISABLED;
>>  	}
>>  
>> -	if (unlikely(evmcs_gpa != vmx->nested.hv_evmcs_vmptr)) {
>> +	if (unlikely(evmcs_gpa != nested_vmx_evmptr(vmx))) {
>>  		vmx->nested.current_vmptr = INVALID_GPA;
>>  
>>  		nested_release_evmcs(vcpu);
>> @@ -2097,7 +2097,7 @@ void nested_sync_vmcs12_to_shadow(struct kvm_vcpu *vcpu)
>>  {
>>  	struct vcpu_vmx *vmx = to_vmx(vcpu);
>>  
>> -	if (evmptr_is_valid(vmx->nested.hv_evmcs_vmptr))
>> +	if (evmptr_is_valid(nested_vmx_evmptr(vmx)))
>>  		copy_vmcs12_to_enlightened(vmx);
>>  	else
>>  		copy_vmcs12_to_shadow(vmx);
>> @@ -2251,7 +2251,7 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx, struct loaded_vmcs *vmcs0
>>  	u32 exec_control;
>>  	u64 guest_efer = nested_vmx_calc_efer(vmx, vmcs12);
>>  
>> -	if (vmx->nested.dirty_vmcs12 || evmptr_is_valid(vmx->nested.hv_evmcs_vmptr))
>> +	if (vmx->nested.dirty_vmcs12 || evmptr_is_valid(nested_vmx_evmptr(vmx)))
>>  		prepare_vmcs02_early_rare(vmx, vmcs12);
>
> There are some similarities between evmcs and shadow vmcs. I used to know this, but it will probably
> take me time to recall all of the gory details.
>
> It might make sense to unify some of the logic, which can make it easier to #ifdef the hyperv support
> in less places.
>
>
>>  
>>  	/*
>> @@ -2546,11 +2546,11 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
>>  	struct vcpu_vmx *vmx = to_vmx(vcpu);
>>  	bool load_guest_pdptrs_vmcs12 = false;
>>  
>> -	if (vmx->nested.dirty_vmcs12 || evmptr_is_valid(vmx->nested.hv_evmcs_vmptr)) {
>> +	if (vmx->nested.dirty_vmcs12 || evmptr_is_valid(nested_vmx_evmptr(vmx))) {
>>  		prepare_vmcs02_rare(vmx, vmcs12);
>>  		vmx->nested.dirty_vmcs12 = false;
>>  
>> -		load_guest_pdptrs_vmcs12 = !evmptr_is_valid(vmx->nested.hv_evmcs_vmptr) ||
>> +		load_guest_pdptrs_vmcs12 = !evmptr_is_valid(nested_vmx_evmptr(vmx)) ||
>>  			!(vmx->nested.hv_evmcs->hv_clean_fields &
>>  			  HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP1);
>>  	}
>> @@ -2673,7 +2673,7 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
>>  	 * bits when it changes a field in eVMCS. Mark all fields as clean
>>  	 * here.
>>  	 */
>> -	if (evmptr_is_valid(vmx->nested.hv_evmcs_vmptr))
>> +	if (evmptr_is_valid(nested_vmx_evmptr(vmx)))
>>  		vmx->nested.hv_evmcs->hv_clean_fields |=
>>  			HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL;
>>  
>> @@ -3181,7 +3181,7 @@ static bool nested_get_evmcs_page(struct kvm_vcpu *vcpu)
>>  	 * properly reflected.
>>  	 */
>>  	if (guest_cpuid_has_evmcs(vcpu) &&
>> -	    vmx->nested.hv_evmcs_vmptr == EVMPTR_MAP_PENDING) {
>> +	    nested_vmx_evmptr(vmx) == EVMPTR_MAP_PENDING) {
>>  		enum nested_evmptrld_status evmptrld_status =
>>  			nested_vmx_handle_enlightened_vmptrld(vcpu, false);
>>  
>> @@ -3551,7 +3551,7 @@ enum nvmx_vmentry_status nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu,
>>  
>>  	load_vmcs12_host_state(vcpu, vmcs12);
>>  	vmcs12->vm_exit_reason = exit_reason.full;
>> -	if (enable_shadow_vmcs || evmptr_is_valid(vmx->nested.hv_evmcs_vmptr))
>> +	if (enable_shadow_vmcs || evmptr_is_valid(nested_vmx_evmptr(vmx)))
>>  		vmx->nested.need_vmcs12_to_shadow_sync = true;
>>  	return NVMX_VMENTRY_VMEXIT;
>>  }
>> @@ -3584,7 +3584,7 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
>>  	if (CC(evmptrld_status == EVMPTRLD_VMFAIL))
>>  		return nested_vmx_failInvalid(vcpu);
>>  
>> -	if (CC(!evmptr_is_valid(vmx->nested.hv_evmcs_vmptr) &&
>> +	if (CC(!evmptr_is_valid(nested_vmx_evmptr(vmx)) &&
>>  	       vmx->nested.current_vmptr == INVALID_GPA))
>>  		return nested_vmx_failInvalid(vcpu);
>>  
>> @@ -3599,7 +3599,7 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
>>  	if (CC(vmcs12->hdr.shadow_vmcs))
>>  		return nested_vmx_failInvalid(vcpu);
>>  
>> -	if (evmptr_is_valid(vmx->nested.hv_evmcs_vmptr)) {
>> +	if (evmptr_is_valid(nested_vmx_evmptr(vmx))) {
>>  		copy_enlightened_to_vmcs12(vmx, vmx->nested.hv_evmcs->hv_clean_fields);
>>  		/* Enlightened VMCS doesn't have launch state */
>>  		vmcs12->launch_state = !launch;
>> @@ -4344,11 +4344,11 @@ static void sync_vmcs02_to_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
>>  {
>>  	struct vcpu_vmx *vmx = to_vmx(vcpu);
>>  
>> -	if (evmptr_is_valid(vmx->nested.hv_evmcs_vmptr))
>> +	if (evmptr_is_valid(nested_vmx_evmptr(vmx)))
>>  		sync_vmcs02_to_vmcs12_rare(vcpu, vmcs12);
>>  
>>  	vmx->nested.need_sync_vmcs02_to_vmcs12_rare =
>> -		!evmptr_is_valid(vmx->nested.hv_evmcs_vmptr);
>> +		!evmptr_is_valid(nested_vmx_evmptr(vmx));
>>  
>>  	vmcs12->guest_cr0 = vmcs12_guest_cr0(vcpu, vmcs12);
>>  	vmcs12->guest_cr4 = vmcs12_guest_cr4(vcpu, vmcs12);
>> @@ -4869,7 +4869,7 @@ void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 vm_exit_reason,
>>  	}
>>  
>>  	if ((vm_exit_reason != -1) &&
>> -	    (enable_shadow_vmcs || evmptr_is_valid(vmx->nested.hv_evmcs_vmptr)))
>> +	    (enable_shadow_vmcs || evmptr_is_valid(nested_vmx_evmptr(vmx))))
>>  		vmx->nested.need_vmcs12_to_shadow_sync = true;
>>  
>>  	/* in case we halted in L2 */
>> @@ -5335,7 +5335,7 @@ static int handle_vmclear(struct kvm_vcpu *vcpu)
>>  					   vmptr + offsetof(struct vmcs12,
>>  							    launch_state),
>>  					   &zero, sizeof(zero));
>> -	} else if (vmx->nested.hv_evmcs && vmptr == vmx->nested.hv_evmcs_vmptr) {
>> +	} else if (vmx->nested.hv_evmcs && vmptr == nested_vmx_evmptr(vmx)) {
>>  		nested_release_evmcs(vcpu);
>>  	}
>>  
>> @@ -5375,7 +5375,7 @@ static int handle_vmread(struct kvm_vcpu *vcpu)
>>  	/* Decode instruction info and find the field to read */
>>  	field = kvm_register_read(vcpu, (((instr_info) >> 28) & 0xf));
>>  
>> -	if (!evmptr_is_valid(vmx->nested.hv_evmcs_vmptr)) {
>> +	if (!evmptr_is_valid(nested_vmx_evmptr(vmx))) {
>>  		/*
>>  		 * In VMX non-root operation, when the VMCS-link pointer is INVALID_GPA,
>>  		 * any VMREAD sets the ALU flags for VMfailInvalid.
>> @@ -5601,7 +5601,7 @@ static int handle_vmptrld(struct kvm_vcpu *vcpu)
>>  		return nested_vmx_fail(vcpu, VMXERR_VMPTRLD_VMXON_POINTER);
>>  
>>  	/* Forbid normal VMPTRLD if Enlightened version was used */
>> -	if (evmptr_is_valid(vmx->nested.hv_evmcs_vmptr))
>> +	if (evmptr_is_valid(nested_vmx_evmptr(vmx)))
>>  		return 1;
>>  
>>  	if (vmx->nested.current_vmptr != vmptr) {
>> @@ -5664,7 +5664,7 @@ static int handle_vmptrst(struct kvm_vcpu *vcpu)
>>  	if (!nested_vmx_check_permission(vcpu))
>>  		return 1;
>>  
>> -	if (unlikely(evmptr_is_valid(to_vmx(vcpu)->nested.hv_evmcs_vmptr)))
>> +	if (unlikely(evmptr_is_valid(nested_vmx_evmptr(to_vmx(vcpu)))))
>>  		return 1;
>>  
>>  	if (get_vmx_mem_address(vcpu, exit_qual, instr_info,
>> @@ -6450,7 +6450,7 @@ static int vmx_get_nested_state(struct kvm_vcpu *vcpu,
>>  			kvm_state.size += sizeof(user_vmx_nested_state->vmcs12);
>>  
>>  			/* 'hv_evmcs_vmptr' can also be EVMPTR_MAP_PENDING here */
>> -			if (vmx->nested.hv_evmcs_vmptr != EVMPTR_INVALID)
>> +			if (nested_vmx_evmptr(vmx) != EVMPTR_INVALID)
>>  				kvm_state.flags |= KVM_STATE_NESTED_EVMCS;
>>  
>>  			if (is_guest_mode(vcpu) &&
>> @@ -6506,7 +6506,7 @@ static int vmx_get_nested_state(struct kvm_vcpu *vcpu,
>>  	} else  {
>>  		copy_vmcs02_to_vmcs12_rare(vcpu, get_vmcs12(vcpu));
>>  		if (!vmx->nested.need_vmcs12_to_shadow_sync) {
>> -			if (evmptr_is_valid(vmx->nested.hv_evmcs_vmptr))
>> +			if (evmptr_is_valid(nested_vmx_evmptr(vmx)))
>>  				/*
>>  				 * L1 hypervisor is not obliged to keep eVMCS
>>  				 * clean fields data always up-to-date while
>> diff --git a/arch/x86/kvm/vmx/nested.h b/arch/x86/kvm/vmx/nested.h
>> index b4b9d51438c6..b389312636e2 100644
>> --- a/arch/x86/kvm/vmx/nested.h
>> +++ b/arch/x86/kvm/vmx/nested.h
>> @@ -3,6 +3,7 @@
>>  #define __KVM_X86_VMX_NESTED_H
>>  
>>  #include "kvm_cache_regs.h"
>> +#include "hyperv.h"
>
> ^ This fixes the build error introduced by patch 6.
>
>>  #include "vmcs12.h"
>>  #include "vmx.h"
>>  
>> @@ -57,7 +58,7 @@ static inline int vmx_has_valid_vmcs12(struct kvm_vcpu *vcpu)
>>  
>>  	/* 'hv_evmcs_vmptr' can also be EVMPTR_MAP_PENDING here */
>>  	return vmx->nested.current_vmptr != -1ull ||
>> -		vmx->nested.hv_evmcs_vmptr != EVMPTR_INVALID;
>> +		nested_vmx_evmptr(vmx) != EVMPTR_INVALID;
>
> However with my suggestion of nested_evmptr_valid(vmx) we 
> can hide that check and avoid the include as well.
>
>>  }
>>  
>>  static inline u16 nested_get_vpid02(struct kvm_vcpu *vcpu)
>
>
> Best regards,
> 	Maxim Levitsky
>
>
>
>
>

-- 
Vitaly


  reply	other threads:[~2023-10-16 13:51 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-10 16:02 [PATCH RFC 00/11] KVM: x86: Make Hyper-V emulation optional (AKA introduce CONFIG_KVM_HYPERV) Vitaly Kuznetsov
2023-10-10 16:02 ` [PATCH RFC 01/11] KVM: x86: xen: Remove unneeded xen context from struct kvm_arch when !CONFIG_KVM_XEN Vitaly Kuznetsov
2023-10-12 19:30   ` Maxim Levitsky
2023-10-10 16:02 ` [PATCH RFC 02/11] KVM: x86: hyper-v: Move Hyper-V partition assist page out of Hyper-V emulation context Vitaly Kuznetsov
2023-10-12 19:35   ` Maxim Levitsky
2023-10-16 12:45     ` Vitaly Kuznetsov
2023-10-10 16:02 ` [PATCH RFC 03/11] KVM: VMX: Split off vmx_onhyperv.{ch} from hyperv.{ch} Vitaly Kuznetsov
2023-10-12 19:36   ` Maxim Levitsky
2023-10-10 16:02 ` [PATCH RFC 04/11] KVM: x86: hyper-v: Introduce kvm_hv_synic_auto_eoi_set() Vitaly Kuznetsov
2023-10-12 19:36   ` Maxim Levitsky
2023-10-10 16:02 ` [PATCH RFC 05/11] KVM: x86: hyper-v: Introduce kvm_hv_synic_has_vector() Vitaly Kuznetsov
2023-10-12 19:36   ` Maxim Levitsky
2023-10-10 16:02 ` [PATCH RFC 06/11] KVM: VMX: Split off hyperv_evmcs.{ch} Vitaly Kuznetsov
2023-10-12 19:40   ` Maxim Levitsky
2023-10-16 12:47     ` Vitaly Kuznetsov
2023-10-10 16:02 ` [PATCH RFC 07/11] KVM: x86: Make Hyper-V emulation optional Vitaly Kuznetsov
2023-10-12 19:49   ` Maxim Levitsky
2023-10-16 12:53     ` Vitaly Kuznetsov
2023-10-16 15:27       ` Sean Christopherson
2023-10-16 15:43         ` Vitaly Kuznetsov
2023-10-16 16:45           ` Sean Christopherson
2023-10-10 16:02 ` [PATCH RFC 08/11] KVM: nVMX: hyper-v: Introduce nested_vmx_evmptr() accessor Vitaly Kuznetsov
2023-10-12 19:50   ` Maxim Levitsky
2023-10-16 13:49     ` Vitaly Kuznetsov [this message]
2023-10-16 16:55       ` Sean Christopherson
2023-10-10 16:02 ` [PATCH RFC 09/11] KVM: nVMX: hyper-v: Introduce nested_vmx_evmcs() accessor Vitaly Kuznetsov
2023-10-12 19:51   ` Maxim Levitsky
2023-10-10 16:02 ` [PATCH RFC 10/11] KVM: nVMX: hyper-v: Hide more stuff under CONFIG_KVM_HYPERV Vitaly Kuznetsov
2023-10-12 19:51   ` Maxim Levitsky
2023-10-10 16:03 ` [PATCH RFC 11/11] KVM: nSVM: hyper-v: Hide more stuff under CONFIG_KVM_HYPERV/CONFIG_HYPERV Vitaly Kuznetsov
2023-10-12 19:51   ` Maxim Levitsky

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87edhu8yoj.fsf@redhat.com \
    --to=vkuznets@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mlevitsk@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=seanjc@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.